Browse Source

ss-local: properly handle SOCKS5

* close the connection if the client doesn't speak SOCKS5
 * check if client supports "no auth. required"
pull/1678/head
Vladimir Olteanu 7 years ago
committed by Max Lv
parent
commit
9201619090
2 changed files with 25 additions and 3 deletions
  1. 26
      src/local.c
  2. 2
      src/socks5.h

26
src/local.c

@ -465,7 +465,14 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
// all processed
return;
} else if (server->stage == STAGE_INIT) {
if (buf->len < sizeof(struct method_select_request) + 1) {
if (buf->len < 1)
return;
if (buf->data[0] != SVERSION) {
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
if (buf->len < sizeof(struct method_select_request)) {
return;
}
struct method_select_request *method = (struct method_select_request *)buf->data;
@ -473,14 +480,27 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
if (buf->len < method_len) {
return;
}
struct method_select_response response;
response.ver = SVERSION;
response.method = 0;
response.method = METHOD_UNACCEPTABLE;
for (int i = 0; i < method->nmethods; i++) {
if (method->methods[i] == METHOD_NOAUTH) {
response.method = METHOD_NOAUTH;
break;
}
}
char *send_buf = (char *)&response;
send(server->fd, send_buf, sizeof(response), 0);
if (response.method == METHOD_UNACCEPTABLE) {
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
server->stage = STAGE_HANDSHAKE;
if (method->ver == SVERSION && method_len < (int)(buf->len)) {
if (method_len < (int)(buf->len)) {
memmove(buf->data, buf->data + method_len , buf->len - method_len);
buf->len -= method_len;
continue;

2
src/socks5.h

@ -28,6 +28,8 @@
#define IPV4 0x01
#define DOMAIN 0x03
#define IPV6 0x04
#define METHOD_NOAUTH 0x00
#define METHOD_UNACCEPTABLE 0xff
#define CMD_NOT_SUPPORTED 0x07
struct method_select_request {

Loading…
Cancel
Save