Finalize socks5

This commit is contained in:
Quentin 2020-02-21 17:55:06 +01:00
parent e3653112a6
commit 00e37ceb88
2 changed files with 118 additions and 35 deletions

View file

@ -376,31 +376,32 @@ error:
int on_socks5_server_recv_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct socks5_ctx* s5ctx = fdinfo->other;
// 1. We have read the whole buffer, change category
if (s5ctx->ch_cursor > 2 && s5ctx->ch_cursor >= s5ctx->ch.nmethods + 2) {
printf("[%s][socks5] read client handshake version: %d, nmethods: %d\n", current_human_datetime (), s5ctx->ch.ver, s5ctx->ch.nmethods);
for (int i = 0; i < s5ctx->ch.nmethods; i++) {
if (s5ctx->ch.methods[i] == METHOD_NOAUTH) {
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-handshake");
return EVT_CORE_FD_EXHAUSTED; // Success, we are compatible with client, moving to next state
}
}
// We failed to find a NOAUTH
fprintf(stderr, "Unable to find a NOAUTH method in the list of available method\n");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
return EVT_CORE_FD_EXHAUSTED;
// 1. We need to read more
if (s5ctx->ch_cursor < 2 || s5ctx->ch_cursor < s5ctx->ch.nmethods + 2) {
size_t to_read = 0;
if (s5ctx->ch_cursor < 2) to_read = 2 - s5ctx->ch_cursor;
else to_read = s5ctx->ch.nmethods - (s5ctx->ch_cursor - 2);
ssize_t nread = recv(fdinfo->fd, ((void*)&s5ctx->ch) + s5ctx->ch_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto serv_handshake_err;
s5ctx->ch_cursor += nread;
return EVT_CORE_FD_UNFINISHED;
}
// 2. We need to read more
size_t to_read = 0;
if (s5ctx->ch_cursor < 2) to_read = 2 - s5ctx->ch_cursor;
else to_read = s5ctx->ch.nmethods - (s5ctx->ch_cursor - 2);
ssize_t nread = recv(fdinfo->fd, ((void*)&s5ctx->ch) + s5ctx->ch_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto serv_handshake_err;
s5ctx->ch_cursor += nread;
printf("[%s][socks5] read client handshake version: %d, nmethods: %d\n", current_human_datetime (), s5ctx->ch.ver, s5ctx->ch.nmethods);
for (int i = 0; i < s5ctx->ch.nmethods; i++) {
if (s5ctx->ch.methods[i] == METHOD_NOAUTH) goto success;
}
fprintf(stderr, "Unable to find a NOAUTH method in the list of available method\n");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
return EVT_CORE_FD_EXHAUSTED;
success:
printf("[%s][socks5] received client handshake handshake\n", current_human_datetime ());
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-handshake");
return EVT_CORE_FD_EXHAUSTED; // Success, we are compatible with client, moving to next state
return EVT_CORE_FD_UNFINISHED;
serv_handshake_err:
perror("[socks5] unable to read handshake from socket.");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
@ -410,19 +411,18 @@ serv_handshake_err:
int on_socks5_server_send_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct socks5_ctx* s5ctx = fdinfo->other;
// 1. We have sent the whole buffer
if (s5ctx->sh_cursor >= sizeof(s5ctx->sh)) {
printf("[%s][socks5] sent server handshake\n", current_human_datetime ());
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-recv-client-req");
return EVT_CORE_FD_EXHAUSTED;
if (s5ctx->sh_cursor < sizeof(s5ctx->sh)) {
ssize_t nsent = send(fdinfo->fd, &s5ctx->sh, sizeof(s5ctx->sh) - s5ctx->sh_cursor, 0);
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nsent == -1) goto send_hs_error;
s5ctx->sh_cursor += nsent;
return EVT_CORE_FD_UNFINISHED;
}
ssize_t nsent = send(fdinfo->fd, &s5ctx->sh, sizeof(s5ctx->sh) - s5ctx->sh_cursor, 0);
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nsent == -1) goto send_hs_error;
s5ctx->sh_cursor += nsent;
printf("[%s][socks5] sent server handshake\n", current_human_datetime ());
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-recv-client-req");
return EVT_CORE_FD_EXHAUSTED;
return EVT_CORE_FD_UNFINISHED;
send_hs_error:
perror("[socks5] unable to send handshake to socket.");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
@ -431,15 +431,89 @@ send_hs_error:
int on_socks5_server_recv_client_req(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct socks5_ctx* s5ctx = fdinfo->other;
ssize_t nread = 0;
size_t to_read = 0;
if (s5ctx->cr_cursor )
size_t fixed_size = ((void*)&s5ctx->cr.dest_addr) - ((void*)&s5ctx->cr);
if (s5ctx->cr_cursor < fixed_size) {
to_read = fixed_size - s5ctx->cr_cursor;
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr) + s5ctx->cr_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto recv_client_req_error;
s5ctx->cr_cursor += nread;
if (nread == to_read) s5ctx->cr_cursor = 0;
else return EVT_CORE_FD_UNFINISHED;
}
return EVT_CORE_FD_UNFINISHED;
if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_DOMAINNAME) {
to_read = sizeof(s5ctx->cr.dest_addr.dns.len) + s5ctx->cr.dest_addr.dns.len - s5ctx->cr_cursor;
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.dns) + s5ctx->cr_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto recv_client_req_error;
s5ctx->cr_cursor += nread;
if (to_read == nread) {
s5ctx->cr_host_read = TRUE;
s5ctx->cr_cursor = 0;
} else return EVT_CORE_FD_UNFINISHED;
} else if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_IPV4) {
to_read = sizeof(s5ctx->cr.dest_addr.ipv4) - s5ctx->cr_cursor;
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.ipv4) + s5ctx->cr_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto recv_client_req_error;
s5ctx->cr_cursor += nread;
if (to_read == nread) {
s5ctx->cr_host_read = TRUE;
s5ctx->cr_cursor = 0;
} else return EVT_CORE_FD_UNFINISHED;
} else if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_IPV6) {
to_read = sizeof(s5ctx->cr.dest_addr.ipv6) - s5ctx->cr_cursor;
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.ipv6) + s5ctx->cr_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto recv_client_req_error;
s5ctx->cr_cursor += nread;
if (to_read == nread) {
s5ctx->cr_host_read = TRUE;
s5ctx->cr_cursor = 0;
} else return EVT_CORE_FD_UNFINISHED;
} else if (!s5ctx->cr_host_read) goto recv_client_req_error;
to_read = ((void*)&s5ctx->cr+1) - ((void*)&s5ctx->cr.port) - s5ctx->cr_cursor;
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.port) + s5ctx->cr_cursor, to_read, 0);
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nread == -1) goto recv_client_req_error;
s5ctx->cr_cursor += nread;
if (to_read != nread) return EVT_CORE_FD_UNFINISHED;
printf("[%s][socks5] received client request atyp=%s: ", current_human_datetime (), atyp_str[s5ctx->cr.atyp]);
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-server-reply");
return EVT_CORE_FD_EXHAUSTED;
recv_client_req_error:
perror("[socks5] unable to receive client request from socket.");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
return EVT_CORE_FD_EXHAUSTED;
}
int on_socks5_server_send_server_reply(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct socks5_ctx* s5ctx = fdinfo->other;
ssize_t nsent = 0;
size_t to_send = s5ctx->sr_size - s5ctx->sr_cursor;
return EVT_CORE_FD_UNFINISHED;
nsent = send(fdinfo->fd, s5ctx->sr_buffer + s5ctx->sr_cursor, to_send, 0);
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
if (nsent == -1) goto send_server_rep_error;
s5ctx->sr_cursor += nsent;
if (nsent != to_send) return EVT_CORE_FD_UNFINISHED;
printf("[%s][socks5] sent server reply\n", current_human_datetime ());
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-sucess");
return EVT_CORE_FD_EXHAUSTED;
send_server_rep_error:
perror("[socks5] unable to send server reply to socket.");
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
return EVT_CORE_FD_EXHAUSTED;
}
void socks5_server_init(struct evt_core_ctx* ctx) {

View file

@ -29,6 +29,14 @@ enum atyp {
ATYP_IPV6 = 0x04
};
static char *atyp_str[] = {
"INVALID",
"IPV4",
"INVALID"
"DOMAIN NAME",
"IPV6"
};
enum ver {
VER_SOCKS5 = 0x05
};
@ -129,6 +137,7 @@ struct socks5_ctx {
size_t cr_size;
size_t sr_size;
uint8_t sr_host_read;
uint8_t cr_host_read;
};
void socks5_init(struct evt_core_ctx* ctx);