diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-11-25 07:58:02 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-11-25 07:58:02 -0500 |
commit | 31f8b4fa65b446a3ae4ce67051a7f0aabcd22a97 (patch) | |
tree | 92d2e18a5381f00abbb2d1cff7285d5f32811b1b /src | |
parent | 68b6d852489157d94b14dcdc9ca729f5a7134c76 (diff) | |
parent | f487da518a9828b194c8f1c8cf6da14955c6bdc4 (diff) | |
download | tor-31f8b4fa65b446a3ae4ce67051a7f0aabcd22a97.tar.gz tor-31f8b4fa65b446a3ae4ce67051a7f0aabcd22a97.zip |
Merge branch 'stream-socks-auth' into bug19859_merged
Diffstat (limited to 'src')
-rw-r--r-- | src/feature/control/control_events.c | 12 | ||||
-rw-r--r-- | src/feature/control/control_fmt.c | 93 | ||||
-rw-r--r-- | src/feature/control/control_fmt.h | 2 | ||||
-rw-r--r-- | src/test/test_controller_events.c | 131 |
4 files changed, 235 insertions, 3 deletions
diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c index 2b7f2a83b8..f88bcfdb9f 100644 --- a/src/feature/control/control_events.c +++ b/src/feature/control/control_events.c @@ -833,13 +833,19 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn)); if (circ && CIRCUIT_IS_ORIGIN(circ)) origin_circ = TO_ORIGIN_CIRCUIT(circ); - send_control_event(EVENT_STREAM_STATUS, - "650 STREAM %"PRIu64" %s %lu %s%s%s%s\r\n", + + { + char *conndesc = entry_connection_describe_status_for_controller(conn); + const char *sp = strlen(conndesc) ? " " : ""; + send_control_event(EVENT_STREAM_STATUS, + "650 STREAM %"PRIu64" %s %lu %s%s%s%s%s%s\r\n", (ENTRY_TO_CONN(conn)->global_identifier), status, origin_circ? (unsigned long)origin_circ->global_identifier : 0ul, - buf, reason_buf, addrport_buf, purpose); + buf, reason_buf, addrport_buf, purpose, sp, conndesc); + tor_free(conndesc); + } /* XXX need to specify its intended exit, etc? */ diff --git a/src/feature/control/control_fmt.c b/src/feature/control/control_fmt.c index e0e77eb2d0..9e7fc42c3b 100644 --- a/src/feature/control/control_fmt.c +++ b/src/feature/control/control_fmt.c @@ -165,6 +165,99 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) return rv; } +/** Allocate and return a description of <b>conn</b>'s current status. */ +char * +entry_connection_describe_status_for_controller(const entry_connection_t *conn) +{ + char *rv; + smartlist_t *descparts = smartlist_new(); + + if (conn->socks_request != NULL) { + // Show username and/or password if available; used by IsolateSOCKSAuth. + if (conn->socks_request->usernamelen > 0) { + char* username_escaped = esc_for_log_len(conn->socks_request->username, + (size_t) conn->socks_request->usernamelen); + smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s", + username_escaped); + tor_free(username_escaped); + } + if (conn->socks_request->passwordlen > 0) { + char* password_escaped = esc_for_log_len(conn->socks_request->password, + (size_t) conn->socks_request->passwordlen); + smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s", + password_escaped); + tor_free(password_escaped); + } + + const char *client_protocol; + // Show the client protocol; used by IsolateClientProtocol. + switch (conn->socks_request->listener_type) + { + case CONN_TYPE_AP_LISTENER: + switch (conn->socks_request->socks_version) + { + case 4: client_protocol = "SOCKS4"; break; + case 5: client_protocol = "SOCKS5"; break; + default: client_protocol = "UNKNOWN"; + } + break; + case CONN_TYPE_AP_TRANS_LISTENER: client_protocol = "TRANS"; break; + case CONN_TYPE_AP_NATD_LISTENER: client_protocol = "NATD"; break; + case CONN_TYPE_AP_DNS_LISTENER: client_protocol = "DNS"; break; + case CONN_TYPE_AP_HTTP_CONNECT_LISTENER: + client_protocol = "HTTPCONNECT"; break; + default: client_protocol = "UNKNOWN"; + } + smartlist_add_asprintf(descparts, "CLIENT_PROTOCOL=%s", + client_protocol); + } + + // Show newnym epoch; used for stream isolation when NEWNYM is used. + smartlist_add_asprintf(descparts, "NYM_EPOCH=%u", + conn->nym_epoch); + + // Show session group; used for stream isolation of multiple listener ports. + smartlist_add_asprintf(descparts, "SESSION_GROUP=%d", + conn->entry_cfg.session_group); + + // Show isolation flags. + smartlist_t *isoflaglist = smartlist_new(); + char *isoflaglist_joined; + if (conn->entry_cfg.isolation_flags & ISO_DESTPORT) { + smartlist_add(isoflaglist, (void *)"DESTPORT"); + } + if (conn->entry_cfg.isolation_flags & ISO_DESTADDR) { + smartlist_add(isoflaglist, (void *)"DESTADDR"); + } + if (conn->entry_cfg.isolation_flags & ISO_SOCKSAUTH) { + smartlist_add(isoflaglist, (void *)"SOCKS_USERNAME"); + smartlist_add(isoflaglist, (void *)"SOCKS_PASSWORD"); + } + if (conn->entry_cfg.isolation_flags & ISO_CLIENTPROTO) { + smartlist_add(isoflaglist, (void *)"CLIENT_PROTOCOL"); + } + if (conn->entry_cfg.isolation_flags & ISO_CLIENTADDR) { + smartlist_add(isoflaglist, (void *)"CLIENTADDR"); + } + if (conn->entry_cfg.isolation_flags & ISO_SESSIONGRP) { + smartlist_add(isoflaglist, (void *)"SESSION_GROUP"); + } + if (conn->entry_cfg.isolation_flags & ISO_NYM_EPOCH) { + smartlist_add(isoflaglist, (void *)"NYM_EPOCH"); + } + isoflaglist_joined = smartlist_join_strings(isoflaglist, ",", 0, NULL); + smartlist_add_asprintf(descparts, "ISO_FIELDS=%s", isoflaglist_joined); + tor_free(isoflaglist_joined); + smartlist_free(isoflaglist); + + rv = smartlist_join_strings(descparts, " ", 0, NULL); + + SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp)); + smartlist_free(descparts); + + return rv; +} + /** Return a longname the node whose identity is <b>id_digest</b>. If * node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is * returned instead. diff --git a/src/feature/control/control_fmt.h b/src/feature/control/control_fmt.h index 6446e37079..213df9504f 100644 --- a/src/feature/control/control_fmt.h +++ b/src/feature/control/control_fmt.h @@ -17,6 +17,8 @@ int write_stream_target_to_buf(entry_connection_t *conn, char *buf, void orconn_target_get_name(char *buf, size_t len, or_connection_t *conn); char *circuit_describe_status_for_controller(origin_circuit_t *circ); +char *entry_connection_describe_status_for_controller(const + entry_connection_t *conn); MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest)); diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c index 9fb2bc7256..9267aa0e43 100644 --- a/src/test/test_controller_events.c +++ b/src/test/test_controller_events.c @@ -16,11 +16,14 @@ #include "core/or/orconn_event.h" #include "core/mainloop/connection.h" #include "feature/control/control_events.h" +#include "feature/control/control_fmt.h" #include "test/test.h" #include "test/test_helpers.h" +#include "core/or/entry_connection_st.h" #include "core/or/or_circuit_st.h" #include "core/or/origin_circuit_st.h" +#include "core/or/socks_request_st.h" static void add_testing_cell_stats_entry(circuit_t *circ, uint8_t command, @@ -537,6 +540,133 @@ test_cntev_orconn_state_proxy(void *arg) UNMOCK(queue_control_event_string); } +static void +test_cntev_format_stream(void *arg) +{ + entry_connection_t *ec = NULL; + char *conndesc = NULL; + (void)arg; + + ec = entry_connection_new(CONN_TYPE_AP, AF_INET); + + char *username = tor_strdup("jeremy"); + char *password = tor_strdup("letmein"); + ec->socks_request->username = username; // steal reference + ec->socks_request->usernamelen = strlen(username); + ec->socks_request->password = password; // steal reference + ec->socks_request->passwordlen = strlen(password); + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "SOCKS_USERNAME=\"jeremy\"")); + tt_assert(strstr(conndesc, "SOCKS_PASSWORD=\"letmein\"")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER; + ec->socks_request->socks_version = 4; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=SOCKS4")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER; + ec->socks_request->socks_version = 5; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=SOCKS5")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_LISTENER; + ec->socks_request->socks_version = 6; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=UNKNOWN")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_TRANS_LISTENER; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=TRANS")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_NATD_LISTENER; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=NATD")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_DNS_LISTENER; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=DNS")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=HTTPCONNECT")); + tor_free(conndesc); + + ec->socks_request->listener_type = CONN_TYPE_OR; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "CLIENT_PROTOCOL=UNKNOWN")); + tor_free(conndesc); + + ec->nym_epoch = 1337; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "NYM_EPOCH=1337")); + tor_free(conndesc); + + ec->entry_cfg.session_group = 4321; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "SESSION_GROUP=4321")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_DESTPORT; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=DESTPORT")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=DESTPORT,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_DESTADDR; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=DESTADDR")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=DESTADDR,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_SOCKSAUTH; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=SOCKS_USERNAME,SOCKS_PASSWORD")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=SOCKS_USERNAME,SOCKS_PASSWORD,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_CLIENTPROTO; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=CLIENT_PROTOCOL")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=CLIENT_PROTOCOL,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_CLIENTADDR; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=CLIENTADDR")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=CLIENTADDR,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_SESSIONGRP; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=SESSION_GROUP")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=SESSION_GROUP,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_NYM_EPOCH; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, "ISO_FIELDS=NYM_EPOCH")); + tt_assert(!strstr(conndesc, "ISO_FIELDS=NYM_EPOCH,")); + tor_free(conndesc); + + ec->entry_cfg.isolation_flags = ISO_DESTPORT | ISO_SOCKSAUTH | ISO_NYM_EPOCH; + conndesc = entry_connection_describe_status_for_controller(ec); + tt_assert(strstr(conndesc, + "ISO_FIELDS=DESTPORT,SOCKS_USERNAME,SOCKS_PASSWORD,NYM_EPOCH")); + tt_assert(!strstr(conndesc, + "ISO_FIELDS=DESTPORT,SOCKS_USERNAME,SOCKS_PASSWORD,NYM_EPOCH,")); + + done: + tor_free(conndesc); + connection_free_minimal(ENTRY_TO_CONN(ec)); +} + #define TEST(name, flags) \ { #name, test_cntev_ ## name, flags, 0, NULL } @@ -548,6 +678,7 @@ struct testcase_t controller_event_tests[] = { TEST(append_cell_stats, TT_FORK), TEST(format_cell_stats, TT_FORK), TEST(event_mask, TT_FORK), + TEST(format_stream, TT_FORK), T_PUBSUB(dirboot_defer_desc, TT_FORK), T_PUBSUB(dirboot_defer_orconn, TT_FORK), T_PUBSUB(orconn_state, TT_FORK), |