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);
}
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) {
// 1. Fetch fd category
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_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);
struct evt_core_cat* evt_core_rm_fd(struct evt_core_ctx* ctx, int fd);
void evt_core_free(struct evt_core_ctx* ctx);

View file

@ -4,8 +4,14 @@ struct socks5_ctx {
struct client_handshake ch;
struct server_handshake sh;
struct client_request cr;
char cr_buffer[262];
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) {
@ -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) {
int sock = create_tcp_client (proxy_host, proxy_port);
struct evt_core_fdinfo fdinfo;
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->name = "socks5-send-handshake";
fdinfo.fd = sock;
@ -25,35 +48,57 @@ void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char*
perror("malloc failed");
exit(EXIT_FAILURE);
}
memset(fdinfo.other, 0, sizeof(struct socks5_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);
}
int socks5_handshake_syn(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct client_handshake ch = {
.ver = 0x05,
.nmethods = 0x01,
.methods = {0x00}
};
int on_socks5_send_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct socks5_ctx* s5ctx = fdinfo->other;
fdinfo->
int size = sizeof(uint8_t) * (2 + ch.nmethods);
if (size != write(sock, &ch, size)) {
perror("write failed on tcp socket in socks5");
return -1;
}
size_t written = write(fdinfo->fd, &s5ctx->ch + s5ctx->ch_cursor, s5ctx->ch_size - s5ctx->ch_cursor);
if (written == -1 && errno == EAGAIN) return 1;
if (written < 0) {
perror("write failed on tcp socket in socks5");
evt_core_mv_fd2(ctx, fdinfo, "socks5-failed");
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) {
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));
int on_socks5_recv_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
if (err == -1) {
perror("sock5 handshake failed read");
return -1;

View file

@ -28,6 +28,17 @@ enum atyp {
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 {
struct {
uint8_t len;