Browse Source

[angel] merge allow_listen_* items

* allow_listen_ip ".." -> allow_listen ".."
 * allow_listen_unix ".." -> allow_listen "unix:.."
 * allow_listen also takes lists of strings
personal/stbuehler/wip
Stefan Bühler 7 years ago
parent
commit
074f53744a
4 changed files with 62 additions and 59 deletions
  1. +7
    -6
      contrib/angel.conf
  2. +15
    -19
      doc/core_config_angel.xml
  3. +37
    -29
      src/angel/angel_plugin_core.c
  4. +3
    -5
      tests/base.py

+ 7
- 6
contrib/angel.conf View File

@ -2,13 +2,14 @@ user "www-data";
max_open_files 16384;
copy_env [ "PATH" ];
# env [ "G_SLICE=always-malloc", "G_DEBUG=gc-friendly" ];
# env [ "G_SLICE=always-malloc", "G_DEBUG=gc-friendly,fatal_criticals" ];
# wrapper [ "/usr/bin/valgrind", "--leak-check=full", "--show-reachable=yes", "--leak-resolution=high" ];
# need separate statements for IPv4 and IPv6. if none are configured, allow port 80 and 443 on all IPv4 and IPv6.
# need separate statements for IPv4 and IPv6. if none are configured, allow
# TCP port 80 and 443 on all IPv4 and IPv6.
# no port means 80 and 443 are allowed:
# allow_listen_ip "0.0.0.0/0";
# allow_listen_ip "[::/0]";
# allow_listen "0.0.0.0/0";
# allow_listen "[::/0]";
# allow_listen_ip "0.0.0.0/0:8080";
# allow_listen_ip "[::/0]:8080";
# allow_listen "0.0.0.0/0:8080";
# allow_listen "[::/0]:8080";

+ 15
- 19
doc/core_config_angel.xml View File

@ -214,35 +214,31 @@
</example>
</item>
<item name="allow_listen_ip">
<short>allow worker to listen on a TCP socket</short>
<parameter name="mask">
<short>network mask (CIDR) + optional port</short>
<item name="allow_listen">
<short>allow worker to listen on sockets</short>
<parameter name="list">
<short>list of network mask (CIDR) + optional port or unix domain socket addresses</short>
</parameter>
<description>
The worker uses the angel to bind TCP sockets; the angel checks whether those binds are allowed. If no @allow_listen_ip@ or @allow_listen_unix@ is specified, all TCP binds (IPv4 and IPv6) using port 80 or 443 are allowed.
IPv4 and IPv6 use different masks (no IPv4 to IPv6 mapping), the network length for the CIDR mask is optional (defaulting to a host address), and the port is optional too (allowing both 80 and 443 if omitted).
<textile>
The worker uses the angel to bind TCP/unix sockets; the angel checks whether those binds are allowed. If no @allow_listen@ is specified, all TCP binds (IPv4 and IPv6) using port 80 or 443 are allowed.
IPv4 and IPv6 use different masks (no IPv4 to IPv6 mapping), the network length for the CIDR mask is optional (defaults to a host address), and the port is optional too (allowing both 80 and 443 if omitted).
Formats:
* TCP on IPv4: @ipv4@, @ipv4:port@, @ipv4/net@, @ipv4/net:port@
* TCP on IPv6: @ipv6@, @ipv6/net@, @[ipv6]@, @[ipv6/net]@, @[ipv6]:port@, @[ipv6/net]:port@
* Unix domain: @unix:/wildcard/path/to/*.socket@
</textile>
</description>
<example>
<description>
Only allow port 8080 for IPv4 and IPv6.
Only allow TCP port 8080 for IPv4 and IPv6 and unix domain socket @/run/lighttpd/internal.sock@.
</description>
<config>
allow_listen_ip "0.0.0.0/0:8080";
allow_listen_ip "[::/0]:8080";
allow_listen [ "0.0.0.0/0:8080", "[::/0]:8080" ];
allow_listen "unix:/run/lighttpd/internal.sock";
</config>
</example>
</item>
<item name="allow_listen_unix">
<short>allow worker to listen on a unix socket</short>
<parameter name="path">
<short>path for a unix socket</short>
</parameter>
<description>
The path can contain wildcards.
</description>
</item>
</section>
</angel-module>

+ 37
- 29
src/angel/angel_plugin_core.c View File

@ -305,41 +305,50 @@ static void core_listen_mask_free(liPluginCoreListenMask *mask) {
g_slice_free(liPluginCoreListenMask, mask);
}
static gboolean core_parse_allow_listen_ip(liServer *srv, liPlugin *p, liValue *value, GError **err) {
static gboolean core_parse_allow_listen(liServer *srv, liPlugin *p, liValue *value, GError **err) {
liPluginCoreConfig *pc = p->data;
liPluginCoreListenMask *mask;
UNUSED(srv);
if (NULL == (value = core_parse_check_parameter_string(value, "allow_listen_ip", err))) return FALSE;
mask = g_slice_new0(liPluginCoreListenMask);
if (li_parse_ipv4(value->data.string->str, &mask->value.ipv4.addr, &mask->value.ipv4.networkmask, &mask->value.ipv4.port)) {
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_IPV4;
} else if (li_parse_ipv6(value->data.string->str, mask->value.ipv6.addr, &mask->value.ipv6.network, &mask->value.ipv6.port)) {
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_IPV6;
} else {
ERROR(srv, "couldn't parse ip/network:port in allow_listen_ip mask '%s'", value->data.string->str);
g_slice_free(liPluginCoreListenMask, mask);
return FALSE;
value = li_value_get_single_argument(value);
if (LI_VALUE_LIST != li_value_type(value)) {
li_value_wrap_in_list(value);
}
g_ptr_array_add(pc->parsing.listen_masks, mask);
return TRUE;
}
LI_VALUE_FOREACH(entry, value)
GString *s;
liPluginCoreListenMask *mask;
static gboolean core_parse_allow_listen_unix(liServer *srv, liPlugin *p, liValue *value, GError **err) {
liPluginCoreConfig *pc = p->data;
liPluginCoreListenMask *mask;
UNUSED(srv);
if (LI_VALUE_STRING != li_value_type(entry)) goto parameter_type_error;
s = entry->data.string;
if (NULL == (value = core_parse_check_parameter_string(value, "allow_listen_unix", err))) return FALSE;
mask = g_slice_new0(liPluginCoreListenMask);
if (li_string_prefix(s, CONST_STR_LEN("unix:/"))) {
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_UNIX;
mask->value.unix_socket.path = li_value_extract_string(entry);
g_string_erase(mask->value.unix_socket.path, 0, 5); /* remove "unix:" prefix */
}
else if (li_parse_ipv4(s->str, &mask->value.ipv4.addr, &mask->value.ipv4.networkmask, &mask->value.ipv4.port)) {
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_IPV4;
}
else if (li_parse_ipv6(s->str, mask->value.ipv6.addr, &mask->value.ipv6.network, &mask->value.ipv6.port)) {
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_IPV6;
}
else {
g_set_error(err, LI_ANGEL_CONFIG_PARSER_ERROR, LI_ANGEL_CONFIG_PARSER_ERROR_PARSE,
"allow_listen: couldn't parse socket address mask '%s'", s->str);
g_slice_free(liPluginCoreListenMask, mask);
return FALSE;
}
mask = g_slice_new0(liPluginCoreListenMask);
mask->type = LI_PLUGIN_CORE_LISTEN_MASK_UNIX;
mask->value.unix_socket.path = li_value_extract_string(value);
g_ptr_array_add(pc->parsing.listen_masks, mask);
LI_VALUE_END_FOREACH()
g_ptr_array_add(pc->parsing.listen_masks, mask);
return TRUE;
parameter_type_error:
g_set_error(err, LI_ANGEL_CONFIG_PARSER_ERROR, LI_ANGEL_CONFIG_PARSER_ERROR_PARSE,
"allow_listen: expecting string list as parameter");
return FALSE;
}
@ -355,8 +364,7 @@ static const liPluginItem core_items[] = {
{ "copy_env", core_parse_copy_env },
{ "max_core_file_size", core_parse_max_core_file_size },
{ "max_open_files", core_parse_max_open_files },
{ "allow_listen_ip", core_parse_allow_listen_ip },
{ "allow_listen_unix", core_parse_allow_listen_unix },
{ "allow_listen", core_parse_allow_listen },
{ NULL, NULL }
};
@ -425,7 +433,7 @@ static gboolean core_check(liServer *srv, liPlugin *p, GError **err) {
UNUSED(err);
cmd = pc->parsing.wrapper;
pc->parsing.wrapper = NULL;
pc->parsing.wrapper = g_ptr_array_new();
if (NULL != pc->parsing.binary) {
g_ptr_array_add(cmd, g_string_free(pc->parsing.binary, FALSE));
@ -457,7 +465,7 @@ static gboolean core_check(liServer *srv, liPlugin *p, GError **err) {
g_ptr_array_add(pc->parsing.env, NULL);
cmdarr = (gchar**) g_ptr_array_free(cmd, FALSE);
envarr = (gchar**) g_ptr_array_free(pc->parsing.env, FALSE);
pc->parsing.env = NULL;
pc->parsing.env = g_ptr_array_new();
user = pc->parsing.user;
pc->parsing.user = NULL;


+ 3
- 5
tests/base.py View File

@ -446,12 +446,10 @@ if request.is_handled {{
if Env.valgrind_leak != "":
suppressions = ', "--suppressions=' + Env.valgrind_leak + '"'
valgrindconfig = """
env [ "G_SLICE=always-malloc", "G_DEBUG=gc-friendly,fatal-criticals,resident-modules" ];
wrapper [ "{valgrind}", "--leak-check=full", "--show-reachable=yes", "--leak-resolution=high" {suppressions} ];
""".format(valgrind = Env.valgrind, suppressions = suppressions)
elif Env.valgrind:
valgrindconfig = """
env [ "G_SLICE=always-malloc", "G_DEBUG=gc-friendly,fatal-criticals,resident-modules" ];
wrapper [ "{valgrind}" ];
""".format(valgrind = Env.valgrind)
@ -460,11 +458,11 @@ binary "{Env.worker}";
config "{Env.lighttpdconf}";
modules_path "{Env.plugindir}";
copy_env [ "PATH" ];
env [ "G_SLICE=always-malloc", "G_DEBUG=gc-friendly,fatal-criticals,resident-modules" ];
{valgrindconfig}
allow_listen_ip "127.0.0.2:{Env.port}";
allow_listen_ip "127.0.0.2:{gnutlsport}";
allow_listen_ip "127.0.0.2:{opensslport}";
allow_listen "127.0.0.2:{Env.port}";
allow_listen ["127.0.0.2:{gnutlsport}", "127.0.0.2:{opensslport}"];
""".format(Env = Env, gnutlsport = Env.port+1, opensslport = Env.port + 2, valgrindconfig = valgrindconfig))
print >> Env.log, "[Done] Preparing tests"


Loading…
Cancel
Save