From 848263bc247acf7c24730a08ed9adef034b58750 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Fri, 8 Feb 2019 17:37:02 +0100 Subject: [PATCH] Debugging tor controller --- CMakeLists.txt | 2 ++ src/donar-proxy.c | 20 +++++++++++-- src/net_tools.h | 1 + src/socks5.h | 1 + src/tor_ctl.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ src/tor_ctl.h | 19 ++++++++++++ src/tor_os.c | 48 ++++++++++++++++++++++++------ src/tor_os.h | 11 +++++-- 8 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 src/tor_ctl.c create mode 100644 src/tor_ctl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a672df..cae8e9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,8 @@ list(APPEND CSOURCES src/socks5.c src/tor_os.h src/tor_os.c + src/tor_ctl.h + src/tor_ctl.c ) add_executable(donar-proxy ${CSOURCES} src/donar-proxy.c) diff --git a/src/donar-proxy.c b/src/donar-proxy.c index fcb819c..7ff25cb 100644 --- a/src/donar-proxy.c +++ b/src/donar-proxy.c @@ -9,14 +9,30 @@ #include #include "socks5.h" #include "tor_os.h" +#include "tor_ctl.h" int main(int argc, char** argv) { printf("~ Donar ~\n"); int sock; struct tor_os_str tos; - tor_os_create (&tos, 10); - tor_os_read (&tos, "onion_services.txt"); + tor_os_create (&tos, "onion_services.txt", 10); + tor_os_read (&tos); + + int ports[10] = { 7500, 7501, 7502, 7503, 7504, 7505, 7506, 7507, 7508, 7509}; + int err = 0; + struct tor_ctl tctl = {}; + err = tor_ctl_connect (&tctl, "127.0.0.1", "9051"); + if (err < 0) { + fprintf(stderr, "Unable to open Tor Socket\n"); + exit(EXIT_FAILURE); + } + err = tor_ctl_add_onion (&tctl, &tos, ports); + if (err != 0) { + fprintf(stderr, "Unable to create Onion Services (error: %d)\n", err); + exit(EXIT_FAILURE); + } + tor_ctl_close (&tctl); tor_os_free (&tos); if (argc < 3) { diff --git a/src/net_tools.h b/src/net_tools.h index d1a9bf0..1a6a2e7 100644 --- a/src/net_tools.h +++ b/src/net_tools.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/src/socks5.h b/src/socks5.h index f879125..46e3cc2 100644 --- a/src/socks5.h +++ b/src/socks5.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/src/tor_ctl.c b/src/tor_ctl.c new file mode 100644 index 0000000..51261be --- /dev/null +++ b/src/tor_ctl.c @@ -0,0 +1,76 @@ +#include "tor_ctl.h" + +int tor_ctl_connect(struct tor_ctl* ctx, char* addr, char* service) { + int sock = create_tcp_client (addr, service); + int sock2 = dup(sock); + ctx->rsock = NULL; + ctx->wsock = NULL; + + ctx->rsock = fdopen(sock, "r"); + if (ctx->rsock == NULL) { + return -1; + } + setbuf(ctx->rsock, NULL); + + ctx->wsock = fdopen(sock2, "w"); + if (ctx->wsock == NULL) { + return -1; + } + setbuf(ctx->wsock, NULL); + + fprintf (ctx->wsock, "authenticate \"\"\n"); + int error_code = 0; + fscanf (ctx->rsock, "%d", &error_code); + if (error_code != 250) { + tor_ctl_close (ctx); + return -1; + } + fscanf(ctx->rsock," OK"); + + return 0; +} + +int tor_ctl_add_onion(struct tor_ctl* ctx, struct tor_os_str* tos, int* port) { + int err = 0; + char buffer[1024] = {0}; + int to_create = tos->size - tos->filled; + + /* Add onion services loaded from file */ + for (int i = 0; i < tos->filled; i++) { + fprintf(ctx->wsock, "add_onion %s Port=%d\n", tos->list[i], port[i]); + fscanf(ctx->rsock, "%d", &err); + if (err != 250) return -1; + fscanf(ctx->rsock, "-ServiceID=%s", buffer); + printf("Added onion service %s from file", buffer); + fscanf(ctx->rsock, "250 OK"); + } + + /* Complete by creating new onion services */ + for (int i = tos->filled; i < tos->size; i++) { + fprintf(ctx->wsock, "add_onion NEW:ED25519-V3 Port=%d\n", port[i]); + + fscanf(ctx->rsock, "%d", &err); + + if (err != 250) return -2; + err = fscanf(ctx->rsock, "-ServiceID=%s\n", buffer); + if (err <= 0) return -3; + printf("Created onion service %s\n", buffer); + err = fscanf(ctx->rsock, "250-PrivateKey=%s\n", buffer); + if (err <= 0) return -4; + printf("Onion service private key: %s\n", buffer); + if (tor_os_append(tos, buffer) != 0) return -5; + err = fscanf(ctx->rsock, "250 OK"); + if (err < 0) return -6; + } + + if (to_create > 0) { + tor_os_persist(tos); + } + + return 0; +} + +void tor_ctl_close(struct tor_ctl* ctx) { + fclose(ctx->rsock); + fclose(ctx->wsock); +} diff --git a/src/tor_ctl.h b/src/tor_ctl.h new file mode 100644 index 0000000..6ab7109 --- /dev/null +++ b/src/tor_ctl.h @@ -0,0 +1,19 @@ +#pragma once +#include "tor_os.h" +#include "net_tools.h" + +/* + * We want to use fscanf and fprintf as these func provide a nice abstraction + * to parse text content. However, we must convert our file descriptor to a + * STREAM*. It appears that we have to create 2 streams (cf link). Moreover + * we have to disable the buffering with setbuf. + * https://ycpcs.github.io/cs365-spring2019/lectures/lecture15.html + */ +struct tor_ctl { + FILE* rsock; + FILE* wsock; +}; + +int tor_ctl_connect(struct tor_ctl* ctx, char* addr, char* service); +int tor_ctl_add_onion(struct tor_ctl* ctx, struct tor_os_str* tos, int* port); +void tor_ctl_close(struct tor_ctl* ctx); diff --git a/src/tor_os.c b/src/tor_os.c index 8014fbc..0b91dc7 100644 --- a/src/tor_os.c +++ b/src/tor_os.c @@ -1,16 +1,23 @@ #include "tor_os.h" -void tor_os_create(struct tor_os_str* os, size_t size) { +void tor_os_create(struct tor_os_str* os, char* file, size_t size) { os->size = size; os->filled = 0; + + os->file = malloc(sizeof(char*) * (strlen(file) + 1)); + if (os->file == NULL) goto mem_error; + strcpy(os->file, file); + os->list = malloc(size * sizeof(char*)); - if (os->list == NULL) { - fprintf(stderr, "unable to allocate memory\n"); - exit(EXIT_FAILURE); - } + if (os->list == NULL) goto mem_error; + return; + +mem_error: + fprintf(stderr, "unable to allocate memory\n"); + exit(EXIT_FAILURE); } -char* tor_os_append(struct tor_os_str* os) { +char* tor_os_append_cursor(struct tor_os_str* os) { if (os->filled == os->size) { return NULL; } @@ -19,16 +26,16 @@ char* tor_os_append(struct tor_os_str* os) { return cur; } -void tor_os_read (struct tor_os_str* os, char* file) { +void tor_os_read (struct tor_os_str* os) { FILE* fd = NULL; - fd = fopen(file, "r"); + fd = fopen(os->file, "r"); if (fd == NULL) { return; } size_t len = 0; int n = 0; while (1) { - char* dst = tor_os_append(os); + char* dst = tor_os_append_cursor(os); if (dst == NULL) break; if (getline(&(os->list[n]),&len,fd) == -1) break; } @@ -40,5 +47,28 @@ void tor_os_free(struct tor_os_str* os) { free(os->list[i]); } free(os->list); + free(os->file); } +void tor_os_persist(struct tor_os_str* os) { + FILE* fd = NULL; + fd = fopen(os->file, "w+"); + if (fd == NULL) { + fprintf(stderr, "unable to open file for writing\n"); + exit(EXIT_FAILURE); + } + + for (int i = 0; i < os->filled; i++) { + fprintf(fd, "%s\n", os->list[i]); + } + + fclose(fd); +} + +int tor_os_append(struct tor_os_str* os, char* entry) { + char* target = tor_os_append_cursor (os); + target = malloc(sizeof(char*) * (strlen(entry) + 1)); + if (target == NULL) return -1; + strcpy (target, entry); + return 0; +} diff --git a/src/tor_os.h b/src/tor_os.h index 26ad5e8..8ed8baa 100644 --- a/src/tor_os.h +++ b/src/tor_os.h @@ -1,15 +1,20 @@ +#pragma once #include #include #include #include +#include struct tor_os_str { size_t filled; size_t size; + char* file; char** list; }; -void tor_os_create(struct tor_os_str* os, size_t size); -char* tor_os_append(struct tor_os_str* os); -void tor_os_read (struct tor_os_str* os, char* file); +void tor_os_create(struct tor_os_str* os, char* file, size_t size); +char* tor_os_append_cursor(struct tor_os_str* os); +int tor_os_append(struct tor_os_str* os, char* entry); +void tor_os_read (struct tor_os_str* os); +void tor_os_persist(struct tor_os_str* os); void tor_os_free(struct tor_os_str* os);