diff options
-rw-r--r-- | buffer.c | 41 | ||||
-rw-r--r-- | buffer.h | 4 | ||||
-rw-r--r-- | init.c | 54 | ||||
-rw-r--r-- | manage.c | 71 | ||||
-rw-r--r-- | manage.h | 1 | ||||
-rw-r--r-- | version.m4 | 2 |
6 files changed, 161 insertions, 12 deletions
@@ -945,7 +945,7 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str) } } -const struct buffer * +struct buffer * buffer_list_peek (struct buffer_list *ol) { if (ol->head) @@ -954,6 +954,45 @@ buffer_list_peek (struct buffer_list *ol) return NULL; } +void +buffer_list_aggregate (struct buffer_list *bl, const size_t max) +{ + if (bl->head) + { + struct buffer_entry *more = bl->head; + size_t size = 0; + int count = 0; + for (count = 0; more && size <= max; ++count) + { + size += BLEN(&more->buf); + more = more->next; + } + + if (count >= 2) + { + int i; + struct buffer_entry *e = bl->head, *f; + + ALLOC_OBJ_CLEAR (f, struct buffer_entry); + f->buf.data = malloc (size); + check_malloc_return (f->buf.data); + f->buf.capacity = size; + for (i = 0; e && i < count; ++i) + { + struct buffer_entry *next = e->next; + buf_copy (&f->buf, &e->buf); + free_buf (&e->buf); + free (e); + e = next; + } + bl->head = f; + f->next = more; + if (!more) + bl->tail = f; + } + } +} + static void buffer_list_pop (struct buffer_list *ol) { @@ -845,9 +845,11 @@ bool buffer_list_defined (const struct buffer_list *ol); void buffer_list_reset (struct buffer_list *ol); void buffer_list_push (struct buffer_list *ol, const unsigned char *str); -const struct buffer *buffer_list_peek (struct buffer_list *ol); +struct buffer *buffer_list_peek (struct buffer_list *ol); void buffer_list_advance (struct buffer_list *ol, int n); +void buffer_list_aggregate (struct buffer_list *bl, const size_t max); + struct buffer_list *buffer_list_file (const char *fn, int max_line_len); #endif @@ -499,6 +499,60 @@ init_static (void) } #endif +#ifdef BUFFER_LIST_AGGREGATE_TEST + /* test buffer_list_aggregate function */ + { + static const char *text[] = { + "It was a bright cold day in April, ", + "and the clocks were striking ", + "thirteen. ", + "Winston Smith, ", + "his chin nuzzled into his breast in an ", + "effort to escape the vile wind, ", + "slipped quickly through the glass doors ", + "of Victory Mansions, though not quickly ", + "enough to prevent a swirl of gritty dust from ", + "entering along with him." + }; + + int iter, listcap; + for (listcap = 0; listcap < 12; ++listcap) + { + for (iter = 0; iter < 512; ++iter) + { + struct buffer_list *bl = buffer_list_new(listcap); + { + int i; + for (i = 0; i < SIZE(text); ++i) + buffer_list_push(bl, (unsigned char *)text[i]); + } + printf("[cap=%d i=%d] *************************\n", listcap, iter); + if (!(iter & 8)) + buffer_list_aggregate(bl, iter/2); + if (!(iter & 16)) + buffer_list_push(bl, (unsigned char *)"Even more text..."); + buffer_list_aggregate(bl, iter); + if (!(iter & 1)) + buffer_list_push(bl, (unsigned char *)"More text..."); + { + struct buffer *buf; + while ((buf = buffer_list_peek(bl))) + { + int c; + printf ("'"); + while ((c = buf_read_u8(buf)) >= 0) + putchar(c); + printf ("'\n"); + buffer_list_advance(bl, 0); + } + } + buffer_list_free(bl); + } + } + return false; + } +#endif + return true; } @@ -97,6 +97,7 @@ man_help () msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason"); msg (M_CLIENT, " text R and optional client reason text CR"); msg (M_CLIENT, "client-kill CID : Kill client instance CID"); + msg (M_CLIENT, "env-filter [level] : Set env-var filter level"); #ifdef MANAGEMENT_PF msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)"); #endif @@ -935,6 +936,13 @@ man_client_n_clients (struct management *man) } } +static void +man_env_filter (struct management *man, const int level) +{ + man->connection.env_filter_level = level; + msg (M_CLIENT, "SUCCESS: env_filter_level=%d", level); +} + #ifdef MANAGEMENT_PF static void @@ -1020,6 +1028,13 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch { man_client_n_clients (man); } + else if (streq (p[0], "env-filter")) + { + int level = 0; + if (p[1]) + level = atoi (p[1]); + man_env_filter (man, level); + } #endif else if (streq (p[0], "signal")) { @@ -1723,13 +1738,15 @@ man_read (struct management *man) static int man_write (struct management *man) { - const int max_send = 256; + const int size_hint = 1024; int sent = 0; + const struct buffer *buf; - const struct buffer *buf = buffer_list_peek (man->connection.out); + buffer_list_aggregate(man->connection.out, size_hint); + buf = buffer_list_peek (man->connection.out); if (buf && BLEN (buf)) { - const int len = min_int (max_send, BLEN (buf)); + const int len = min_int (size_hint, BLEN (buf)); sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL); if (sent >= 0) { @@ -2130,15 +2147,51 @@ management_set_state (struct management *man, #ifdef MANAGEMENT_DEF_AUTH +static bool +env_filter_match (const char *env_str, const int env_filter_level) +{ + static const char *env_names[] = { + "username=", + "password=", + "X509_0_CN=", + "tls_serial_0=", + "untrusted_ip=", + "ifconfig_local=", + "ifconfig_netmask=", + "daemon_start_time=", + "daemon_pid=", + "dev=", + "ifconfig_pool_remote_ip=", + "ifconfig_pool_netmask=", + "time_duration=", + "bytes_sent=", + "bytes_received=" + }; + if (env_filter_level >= 1) + { + size_t i; + for (i = 0; i < SIZE(env_names); ++i) + { + const char *en = env_names[i]; + const size_t len = strlen(en); + if (strncmp(env_str, en, len) == 0) + return true; + } + return false; + } + else + return true; +} + static void -man_output_env (const struct env_set *es, const bool tail) +man_output_env (const struct env_set *es, const bool tail, const int env_filter_level) { if (es) { struct env_item *e; for (e = es->list; e != NULL; e = e->next) { - if (e->string) + if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level))) msg (M_CLIENT, ">CLIENT:ENV,%s", e->string); } } @@ -2156,7 +2209,7 @@ man_output_extra_env (struct management *man) const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg); setenv_int (es, "n_clients", nclients); } - man_output_env (es, false); + man_output_env (es, false, man->connection.env_filter_level); gc_free (&gc); } @@ -2173,7 +2226,7 @@ management_notify_client_needing_auth (struct management *management, mode = "REAUTH"; msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id); man_output_extra_env (management); - man_output_env (es, true); + man_output_env (es, true, management->connection.env_filter_level); mdac->flags |= DAF_INITIAL_AUTH; } } @@ -2186,7 +2239,7 @@ management_connection_established (struct management *management, mdac->flags |= DAF_CONNECTION_ESTABLISHED; msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid); man_output_extra_env (management); - man_output_env (es, true); + man_output_env (es, true, management->connection.env_filter_level); } void @@ -2197,7 +2250,7 @@ management_notify_client_close (struct management *management, if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED)) { msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid); - man_output_env (es, true); + man_output_env (es, true, management->connection.env_filter_level); mdac->flags |= DAF_CONNECTION_CLOSED; } } @@ -268,6 +268,7 @@ struct man_connection { unsigned long in_extra_cid; unsigned int in_extra_kid; struct buffer_list *in_extra; + int env_filter_level; #endif struct event_set *es; @@ -1,5 +1,5 @@ dnl define the OpenVPN version -define(PRODUCT_VERSION,[2.1.1e]) +define(PRODUCT_VERSION,[2.1.1f]) dnl define the TAP version define(PRODUCT_TAP_ID,[tap0901]) define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9]) |