commit 7eb36a85f4884668a259040e5dcb2350ed3b0595 Author: George Kadianakis desnacked@gmail.com Date: Tue May 24 16:43:28 2011 +0200
We can now send 'SOCKS5_FAILED_UNSUPPORTED' replies as well! --- src/network.c | 13 +++++++++++-- src/socks.c | 22 ++++++++++++---------- src/socks.h | 3 +++ 3 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/src/network.c b/src/network.c index 835dff1..1f68804 100644 --- a/src/network.c +++ b/src/network.c @@ -268,6 +268,15 @@ socks_read_cb(struct bufferevent *bev, void *arg) return; /* need to read more data. */ else if (r == -1) conn_free(conn); /* XXXX maybe send socks reply */ + else if (r == -2) { + bufferevent_enable(bev, EV_WRITE); + bufferevent_disable(bev, EV_READ); + socks5_send_reply(bufferevent_get_output(bev), conn->socks_state, + SOCKS5_FAILED_UNSUPPORTED); + bufferevent_setcb(bev, NULL, + close_conn_on_flush, output_event_cb, conn); + return; + } }
static void @@ -399,8 +408,8 @@ output_event_cb(struct bufferevent *bev, short what, void *arg) * socks client */ socks_state_set_address(conn->socks_state, sa); } - socks_send_reply(conn->socks_state, bufferevent_get_output(conn->input), - 0); + socks_send_reply(conn->socks_state, + bufferevent_get_output(conn->input), 0); /* we sent a socks reply. We can finally move over to being a regular input bufferevent. */ socks_state_free(conn->socks_state); diff --git a/src/socks.c b/src/socks.c index a388363..367c2f1 100644 --- a/src/socks.c +++ b/src/socks.c @@ -90,13 +90,13 @@ socks_errno_to_reply(socks_state_t *state, int error) return SOCKS5_FAILED_GENERAL; } } - } - return -1; + } else + return -1; }
/** Takes a command request from 'source', it evaluates it and if it's - legit it parses into 'parsereq'. + legit it parses it into 'parsereq'.
It returns '1' if everything went fine. It returns '0' if we need more data from the client. @@ -138,6 +138,7 @@ socks5_handle_request(struct evbuffer *source, struct parsereq *parsereq) printf("socks: Corrupted packet. Discarding.\n"); goto err; } + if (p[1] != SOCKS5_CMD_CONNECT) return -2; /* We must send reply to the client. */
@@ -495,13 +496,14 @@ handle_socks(struct evbuffer *source, struct evbuffer *dest, if (socks_state->state == ST_NEGOTIATION_DONE) { /* We know this connection. Let's see what it wants. */ r = socks5_handle_request(source,&socks_state->parsereq); - if (r == -1) - goto broken; - else if (r == -2) { - socks5_send_reply(dest,socks_state, - SOCKS5_FAILED_UNSUPPORTED); + if (r == -2) { /* Request CMD != CONNECT. */ + socks_state->broken = 1; + return -2; + } else if (r == -1) /* Broken request. */ goto broken; - } else if (r == 1) + else if (r == 0) /* Incomplete. */ + return 0; + else if (r == 1) /* Neat request. */ socks_state->state = ST_HAVE_ADDR; return r; } @@ -565,6 +567,7 @@ socks_state_set_address(socks_state_t *state, const struct sockaddr *sa) }
/** + This function sends a SOCKS{5,4} "Server Reply" to 'dest'. 'error' is 0 if no errors were encountered during the SOCKS operation (normally a CONNECT with no errors means that the connect() was successful). @@ -582,4 +585,3 @@ socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error) else return -1; } - diff --git a/src/socks.h b/src/socks.h index 01a76ff..09ebe28 100644 --- a/src/socks.h +++ b/src/socks.h @@ -28,6 +28,9 @@ int socks_state_get_address(const socks_state_t *state, int *port_out); int socks_state_set_address(socks_state_t *state, const struct sockaddr *sa); int socks_send_reply(socks_state_t *state, struct evbuffer *dest, int error); +int socks5_send_reply(struct evbuffer *reply_dest, + socks_state_t *state, int status); +
#define SOCKS_SUCCESS 0x0 #define SOCKS_FAILED 0x01
tor-commits@lists.torproject.org