WIP socks5 - refactor socks5

This commit is contained in:
Quentin Dufour 2019-03-25 15:26:30 +01:00
parent 1437f48042
commit 9d4aae315e
4 changed files with 110 additions and 133 deletions

View file

@ -5,121 +5,69 @@ void load_onion_services(struct donar_client_ctx* ctx, char* onion_file, int por
tor_os_read (&(ctx->tos));
}
void init_tcp_client(struct donar_client_ctx* ctx, int i) {
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
char url_buf[255];
int err;
ctx->ports[i] = 7500 + i;
cat.name = "configure-socks5";
fdinfo.cat = &cat;
fdinfo.url = url_buf;
while (1) {
fdinfo.fd = create_tcp_client("127.0.0.1", "9050");
if (fdinfo.fd < 0) goto failed_socks5;
ctx->client_sock[i].fd = fdinfo.fd;
ctx->client_sock[i].state = SOCKS5_STATE_NEW;
sprintf(url_buf, "socks5:dist:%d", i);
evt_core_add_fd (&(ctx->evts), &fdinfo);
//@FIXME: We suppose that we will be able to do the whole write at once which is wrong
err = socks5_handshake_syn(fdinfo.fd);
if (err) goto failed_socks5;
break;
failed_socks5:
fprintf(stderr, "Failed connection for socket %d/%d. Sleeping 2 seconds...\n",i+1, CLIENT_PORT_SIZE);
close(fdinfo.fd);
sleep(2);
}
}
int configure_tcp_clients(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
int err, pos;
struct donar_client_ctx* app_ctx = (struct donar_client_ctx*) fdinfo->cat->app_ctx;
pos = -1;
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
if (app_ctx->client_sock[i].fd == fdinfo->fd) {
pos = i;
}
}
char target_host[255];
void init_socks5_client(struct donar_client_ctx* app_ctx, int pos) {
char target_host[255];
if (strlen(app_ctx->tos.keys[pos].pub) > 254) {
fprintf(stderr, "Domain name is too long\n");
exit(EXIT_FAILURE);
}
sprintf(target_host, "%s.onion", app_ctx->tos.keys[pos].pub);
switch (app_ctx->client_sock[pos].state) {
case SOCKS5_STATE_NEW:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong
err = socks5_handshake_ack (fdinfo->fd);
if (err < 0) goto on_socks5_err;
//@FIXME: We suppose that we will be able to do the whole write at once which is wrong too
err = socks5_connect_dns(fdinfo->fd, target_host, app_ctx->ports[pos]);
if (err < 0) goto on_socks5_err;
app_ctx->client_sock[pos].state = SOCKS5_STATE_ACK;
printf("Socket %d/%d %s:%d is connecting...\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
break;
case SOCKS5_STATE_ACK:
//@FIXME: We suppose that we will be able to do the whole read at once which is wrong too
err = socks5_reply (fdinfo->fd);
if (err == -SOCKS5_REP_GENERAL_FAILURE || err == -SOCKS5_REP_TTLEXP || err == -SOCKS5_REP_HOSTUNREACH) {
fprintf(stderr, "%s is not ready, received %s\n", fdinfo->url, socks5_rep(-err));
goto on_socks5_err;
} else if (err < 0) {
fprintf(stderr, "An other error occured on %s\n", fdinfo->url);
exit(EXIT_FAILURE);
}
app_ctx->client_sock[pos].state = SOCKS5_STATE_RDY;
int sock1, sock2;
sock1 = dup(fdinfo->fd);
sock2 = dup(fdinfo->fd);
if (sock1 < 0 || sock2 < 0) {
exit(EXIT_FAILURE);
}
void* fdcat = evt_core_rm_fd (ctx, fdinfo->fd);
if (fdcat == NULL) {
exit(EXIT_FAILURE);
}
struct evt_core_fdinfo fdinfo = {0};
struct evt_core_cat cat = {0};
char url[1024];
fdinfo.cat = &cat;
fdinfo.url = url;
app_ctx->ports[pos] = 7500 + pos;
socks5_create_dns_client (&app_ctx->evts, "127.0.0.1", "9050", target_host, app_ctx->ports[pos]);
}
fdinfo.cat->name = "tcp-write";
fdinfo.fd = sock1;
sprintf(fdinfo.url, "tcp:write:127.0.0.1:%d", app_ctx->ports[pos]);
evt_core_add_fd (ctx, &fdinfo);
int on_socks5_success(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct evt_core_fdinfo fdinfo_n = {0};
struct evt_core_cat cat_n = {0};
struct socks5_ctx* s5ctx = fdinfo->other;
fdinfo_n.cat = &cat_n;
int ret = 0;
fdinfo.cat->name = "tcp-read";
fdinfo.fd = sock2;
sprintf(fdinfo.url, "tcp:read:127.0.0.1:%d", app_ctx->ports[pos]);
evt_core_add_fd (ctx, &fdinfo);
fdinfo_n.fd = dup(fdinfo->fd);
fdinfo_n.cat->name = "tcp-write";
ret = asprintf(&fdinfo_n.url, "tcp:write:127.0.0.1:%d", s5ctx->port);
if (ret < 0) goto failed;
evt_core_add_fd (ctx, &fdinfo_n);
printf("Socket %d/%d %s:%d has been added to the pool!\n", pos+1, CLIENT_PORT_SIZE, target_host, app_ctx->ports[pos]);
break;
case SOCKS5_STATE_RDY:
goto on_socks5_err;
break;
case SOCKS5_STATE_ERR:
goto on_socks5_err;
break;
}
fdinfo_n.fd = dup(fdinfo->fd);
fdinfo_n.cat->name = "tcp-read";
ret = asprintf(&fdinfo_n.url, "tcp:read:127.0.0.1:%d", s5ctx->port);
if (ret < 0) goto failed;
evt_core_add_fd (ctx, &fdinfo_n);
return 1;
on_socks5_err:
//perror("An error occured while connecting to an Onion Service");
app_ctx->client_sock[pos].state = SOCKS5_STATE_ERR;
evt_core_rm_fd (ctx, fdinfo->fd);
sleep(2);
init_tcp_client (app_ctx, pos);
return 1;
evt_core_rm_fd (ctx, fdinfo->fd);
return 1;
failed:
fprintf(stderr, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
int on_socks5_failed(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
struct donar_client_ctx* app_ctx = fdinfo->cat->app_ctx;
struct socks5_ctx* s5ctx = fdinfo->other;
int pos = 7500 - s5ctx->port;
evt_core_rm_fd (ctx, fdinfo->fd);
init_socks5_client (app_ctx, pos);
return 1;
}
void init_socks5_sinks(struct donar_client_ctx* app_ctx) {
struct evt_core_cat template = { 0 };
template.cb = on_socks5_success;
template.name = "socks5-success";
template.flags = EPOLLET;
evt_core_add_cat(&app_ctx->evts, &template);
template.cb = on_socks5_failed;
template.app_ctx = app_ctx;
template.name = "socks5-failed";
template.flags = EPOLLET;
evt_core_add_cat(&app_ctx->evts, &template);
}
void donar_client(struct donar_client_ctx* ctx, char* algoname,
@ -128,16 +76,8 @@ void donar_client(struct donar_client_ctx* ctx, char* algoname,
evt_core_init (&(ctx->evts));
init_algo(&ctx->evts, &algo, algoname);
struct evt_core_cat init_socks5 = {
.app_ctx = ctx,
.free_app_ctx = NULL,
.cb = configure_tcp_clients,
.err_cb = NULL,
.name = "configure-socks5",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
evt_core_add_cat (&(ctx->evts), &init_socks5);
socks5_init (&ctx->evts);
init_socks5_sinks(ctx);
evt_core_add_cat (&(ctx->evts), &(algo.on_tcp_co));
evt_core_add_cat (&(ctx->evts), &(algo.on_udp_read));
evt_core_add_cat (&(ctx->evts), &(algo.on_tcp_read));
@ -149,7 +89,7 @@ void donar_client(struct donar_client_ctx* ctx, char* algoname,
printf("--- Onion services loaded\n");
for (int i = 0; i < CLIENT_PORT_SIZE; i++) {
init_tcp_client(ctx, i);
init_socks5_client(ctx, i);
}
printf("--- TCP Clients Connected\n");

View file

@ -1,4 +1,5 @@
#pragma once
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <gmodule.h>

View file

@ -1,26 +1,11 @@
#include "socks5.h"
struct socks5_ctx {
struct client_handshake ch;
struct server_handshake sh;
struct client_request cr;
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;
uint8_t sr_host_read;
};
void socks5_free_ctx(void* elem) {
struct socks5_ctx* ctx = elem;
free(ctx);
}
void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) {
void socks5_create_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port) {
struct evt_core_fdinfo fdinfo;
struct evt_core_cat cat;
struct socks5_ctx* s5ctx;
@ -57,6 +42,7 @@ void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char*
// 3. Fill socks5_ctx structures
s5ctx = fdinfo.other;
s5ctx->port = port;
// 3.1 Client handshake to send
s5ctx->ch.ver = VER_SOCKS5;
@ -292,6 +278,39 @@ move_to_failed:
return 1;
}
int on_socks5_err(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
evt_core_mv_fd2 (ctx, fdinfo, "socks5-failed");
return 1;
}
void socks5_init(struct evt_core_ctx* ctx) {
struct evt_core_cat template = {0};
template.cb = on_socks5_send_handshake;
template.err_cb = on_socks5_err;
template.name = "socks5-send-handshake";
template.flags = EPOLLOUT | EPOLLET;
evt_core_add_cat (ctx, &template);
template.cb = on_socks5_recv_handshake;
template.err_cb = on_socks5_err;
template.name = "socks5-recv-handshake";
template.flags = EPOLLIN | EPOLLET;
evt_core_add_cat (ctx, &template);
template.cb = on_socks5_send_client_req;
template.err_cb = on_socks5_err;
template.name = "socks5-send-client-req";
template.flags = EPOLLOUT | EPOLLET;
evt_core_add_cat(ctx, &template);
template.cb = on_socks5_recv_server_reply;
template.err_cb = on_socks5_err;
template.name = "socks5-recv-server-reply";
template.flags = EPOLLIN | EPOLLET;
evt_core_add_cat(ctx, &template);
}
char* socks5_rep (enum socks5_rep rep) {
return rep_msg[rep];
}

View file

@ -107,6 +107,23 @@ struct server_reply {
uint16_t port;
};
void init_socks5(struct evt_core_ctx* ctx);
void create_socks5_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port);
struct socks5_ctx {
uint16_t port;
struct client_handshake ch;
struct server_handshake sh;
struct client_request cr;
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;
uint8_t sr_host_read;
};
void socks5_init(struct evt_core_ctx* ctx);
void socks5_create_dns_client(struct evt_core_ctx* ctx, char* proxy_host, char* proxy_port, char* addr, uint16_t port);
char* socks5_rep (enum socks5_rep rep);