WIP eventing socks5

This commit is contained in:
Quentin Dufour 2019-03-21 18:43:38 +01:00
parent f43437978c
commit f5c4669b7c
4 changed files with 105 additions and 23 deletions

View file

@ -64,6 +64,30 @@ void evt_core_add_cat(struct evt_core_ctx* ctx, struct evt_core_cat* cat) {
g_hash_table_insert (ctx->catlist, dyn->name, dyn); g_hash_table_insert (ctx->catlist, dyn->name, dyn);
} }
void evt_core_mv_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, struct evt_core_cat* to_cat) {
// 1. Update old category
for (int i = 0; i < fdinfo->cat->socklist->len; i++) {
if (g_array_index(fdinfo->cat->socklist, struct evt_core_fdinfo*, i) == fdinfo) {
g_array_remove_index(fdinfo->cat->socklist, i);
}
}
// 2. Set new cat for fdinfo
fdinfo->cat = to_cat;
// 3. Update new category
g_array_append_val (fdinfo->cat->socklist, fdinfo);
}
void evt_core_mv_fd2(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, char* to_cat) {
struct evt_core_cat* cat = evt_core_get_from_cat (ctx, to_cat);
if (cat == NULL) {
fprintf(stderr, "Category %s does not exist\n", to_cat);
exit(EXIT_FAILURE);
}
evt_core_mv_fd (ctx, fdinfo, cat);
}
void evt_core_add_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* user_data) { void evt_core_add_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* user_data) {
// 1. Fetch fd category // 1. Fetch fd category
struct evt_core_cat* cat = g_hash_table_lookup(ctx->catlist, user_data->cat->name); struct evt_core_cat* cat = g_hash_table_lookup(ctx->catlist, user_data->cat->name);

View file

@ -45,6 +45,8 @@ struct evt_core_fdinfo {
void evt_core_init(struct evt_core_ctx* ctx); void evt_core_init(struct evt_core_ctx* ctx);
void evt_core_add_cat(struct evt_core_ctx* ctx, struct evt_core_cat* cat); void evt_core_add_cat(struct evt_core_ctx* ctx, struct evt_core_cat* cat);
void evt_core_mv_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, struct evt_core_cat* to_cat);
void evt_core_mv_fd2(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, char* to_cat);
void evt_core_add_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* user_data); void evt_core_add_fd(struct evt_core_ctx* ctx, struct evt_core_fdinfo* user_data);
struct evt_core_cat* evt_core_rm_fd(struct evt_core_ctx* ctx, int fd); struct evt_core_cat* evt_core_rm_fd(struct evt_core_ctx* ctx, int fd);
void evt_core_free(struct evt_core_ctx* ctx); void evt_core_free(struct evt_core_ctx* ctx);

View file

@ -4,8 +4,14 @@ struct socks5_ctx {
struct client_handshake ch; struct client_handshake ch;
struct server_handshake sh; struct server_handshake sh;
struct client_request cr; struct client_request cr;
char cr_buffer[262];
struct server_reply sr; struct server_reply sr;
uint64_t ch_cursor;
uint64_t sh_cursor;
uint64_t cr_cursor;
uint64_t sr_cursor;
char cr_buffer[262];
size_t ch_size;
size_t cr_size;
}; };
void socks5_free_ctx(void* elem) { void socks5_free_ctx(void* elem) {
@ -14,9 +20,26 @@ void socks5_free_ctx(void* elem) {
} }
void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) { void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) {
int sock = create_tcp_client (proxy_host, proxy_port);
struct evt_core_fdinfo fdinfo; struct evt_core_fdinfo fdinfo;
struct evt_core_cat cat; struct evt_core_cat cat;
struct socks5_ctx* s5ctx;
char url[1024];
// 0. Compute domain length and enforce an upper bound on its size
size_t domainLength = strlen(addr);
if (domainLength > 255) {
fprintf(stderr, "domain is too long\n");
exit(EXIT_FAILURE);
}
// 1. Open connection
int sock = create_tcp_client (proxy_host, proxy_port);
if (sock < 0) {
fprintf(stderr, "Unable to connect to proxy %s:%s\n", proxy_host, proxy_port);
exit(EXIT_FAILURE);
}
// 2. Create fdinfo
fdinfo.cat = &cat; fdinfo.cat = &cat;
fdinfo.cat->name = "socks5-send-handshake"; fdinfo.cat->name = "socks5-send-handshake";
fdinfo.fd = sock; fdinfo.fd = sock;
@ -25,35 +48,57 @@ void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char*
perror("malloc failed"); perror("malloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
memset(fdinfo.other, 0, sizeof(struct socks5_ctx));
fdinfo.free_other = socks5_free_ctx; fdinfo.free_other = socks5_free_ctx;
sprintf(url, "socks5:send-hs:%s:%d", addr, port);
fdinfo.url = strdup(url);
// 3. Fill socks5_ctx structures
s5ctx = fdinfo.other;
// 3.1 Client handshake to send
s5ctx->ch.ver = VER_SOCKS5;
s5ctx->ch.nmethods = 0x01;
s5ctx->ch.methods[0] = METHOD_NOAUTH;
s5ctx->ch_size = sizeof(uint8_t) * (2 + s5ctx->ch.nmethods);
// 3.2 Client request to send
s5ctx->cr.ver = VER_SOCKS5;
s5ctx->cr.cmd = CMD_CONNECT;
s5ctx->cr.rsv = 0x00;
s5ctx->cr.atyp = ATYP_DOMAINNAME;
s5ctx->cr.dst_addr_len = domainLength;
s5ctx->cr.dst_addr = addr;
s5ctx->cr.port = htons(port);
// 3.3 Generate client request buffer
s5ctx->cr_size = 0;
fill_buffer(&s5ctx->cr_size, s5ctx->cr_buffer, &s5ctx->cr, 5*sizeof(uint8_t));
fill_buffer(&s5ctx->cr_size, s5ctx->cr_buffer, s5ctx->cr.dst_addr, s5ctx->cr.dst_addr_len*sizeof(char));
fill_buffer(&s5ctx->cr_size, s5ctx->cr_buffer, &s5ctx->cr.port, sizeof(uint16_t));
evt_core_add_fd (ctx, &fdinfo); evt_core_add_fd (ctx, &fdinfo);
} }
int socks5_handshake_syn(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) { int on_socks5_send_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct client_handshake ch = { struct socks5_ctx* s5ctx = fdinfo->other;
.ver = 0x05,
.nmethods = 0x01,
.methods = {0x00}
};
fdinfo-> size_t written = write(fdinfo->fd, &s5ctx->ch + s5ctx->ch_cursor, s5ctx->ch_size - s5ctx->ch_cursor);
if (written == -1 && errno == EAGAIN) return 1;
int size = sizeof(uint8_t) * (2 + ch.nmethods); if (written < 0) {
if (size != write(sock, &ch, size)) { perror("write failed on tcp socket in socks5");
perror("write failed on tcp socket in socks5"); evt_core_mv_fd2(ctx, fdinfo, "socks5-failed");
return -1;
}
return 0; return 0;
}
s5ctx->ch_cursor += written;
if (s5ctx->ch_cursor < s5ctx->ch_size) return 0;
evt_core_mv_fd2(ctx, fdinfo, "socks5-recv-handshake");
return 0;
} }
int socks5_handshake_ack(int sock) { int on_socks5_recv_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct client_handshake ch = {
.ver = 0x05,
.nmethods = 0x01,
.methods = {0x00}
};
struct server_handshake sh = {0};
int err = read_entity(sock, &sh, sizeof(struct server_handshake));
if (err == -1) { if (err == -1) {
perror("sock5 handshake failed read"); perror("sock5 handshake failed read");
return -1; return -1;

View file

@ -28,6 +28,17 @@ enum atyp {
ATYP_IPV6 = 0x04 ATYP_IPV6 = 0x04
}; };
enum ver {
VER_SOCKS5 = 0x05
};
enum methods {
METHOD_NOAUTH = 0x00,
METHOD_GSSAPI = 0x01,
METHOD_USERPASS = 0x02,
METHOD_NOACCEPT = 0xff
};
union socks5_addr { union socks5_addr {
struct { struct {
uint8_t len; uint8_t len;