From 9561b7cac93872ccd378cb94b79c89bebfba0f1e Mon Sep 17 00:00:00 2001
From: Santiago Lo Coco <slococo@itba.edu.ar>
Date: Tue, 21 Jun 2022 07:57:03 -0300
Subject: [PATCH] Fix more bugs

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
---
 .gitignore                   |  6 ++++
 README.md                    |  5 ++++
 docs/{rfc.txt => rfcBCP.txt} |  5 ++--
 src/args.c                   | 19 +++++++++++++
 src/client.c                 |  8 ++++--
 src/server.c                 | 54 ++++++++++++++----------------------
 src/socks5nio.c              |  6 ++--
 7 files changed, 64 insertions(+), 39 deletions(-)
 rename docs/{rfc.txt => rfcBCP.txt} (96%)

diff --git a/.gitignore b/.gitignore
index ed0d0ae..d57acf5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,9 @@ a.out
 PVS-Studio.log
 report.tasks
 strace_out
+
+## Docs
+pruebas.txt
+rfc1928.txt
+rfc1929.txt
+enunciado.txt
diff --git a/README.md b/README.md
index db285f7..53b2246 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,10 @@ BProxy (Bottler Proxy)
   - [Requisitos <a name="requisitos"></a>](#requisitos-)
   - [Compilación <a name="compilación"></a>](#compilación-)
   - [Ejecución <a name="ejecución"></a>](#ejecución-)
+  - [Casos de uso <a name="casos-de-uso"></a>](#casos-de-uso-)
   - [Testeos <a name="tests"></a>](#testeos-)
   - [Limpieza <a name="limpieza"></a>](#limpieza-)
+  - [Documentación <a name="documentación"></a>](#documentación-)
 
 ## Requisitos <a name="requisitos"></a>
 
@@ -92,6 +94,9 @@ Si desea borrar los archivos creados luego de la compilación (y los testeos si
 make clean
 ```
 
+## Documentación <a name="documentación"></a>
+Debe notar que el informe y el rfc del protocolo BCP se encuentran en la carpeta `docs/`.
+
 # Autores
 ### Bottler:
    - Barmasch, Juan Martín (61033)
diff --git a/docs/rfc.txt b/docs/rfcBCP.txt
similarity index 96%
rename from docs/rfc.txt
rename to docs/rfcBCP.txt
index 2819196..379a8f3 100644
--- a/docs/rfc.txt
+++ b/docs/rfcBCP.txt
@@ -14,7 +14,8 @@ Note:
    field. When the size of a field is a range, it indicates that the
    corresponding field has a variable length defined either by an
    associated (one or two octet) length field.
-   Fields taking more than one octet are in network octet order.
+
+   Also, fields taking more than one octet are in network octet order.
 
 2.  Requests
 
@@ -454,7 +455,7 @@ Note:
              o  X'D0' VERSION NOT SUPPORTED
              o  X'FF' METHOD NOT SUPPORTED
 
-4. Considerations
+4.  Considerations
 
    If an invalid CMD is requested to a server, it must
    respond with a package such as:
diff --git a/src/args.c b/src/args.c
index 48f574d..1a61135 100644
--- a/src/args.c
+++ b/src/args.c
@@ -63,7 +63,26 @@ static void usage(const char *progname) {
     exit(1);
 }
 
+static void print_logo() {
+    printf("\033[0;36m");
+    printf("$$\\\n"                                                         
+    "$$ |\n"                                                        
+    "$$ |\n"                                                        
+    "$$$$$$$\\   $$$$$$\\   $$$$$$\\   $$$$$$\\  $$\\   $$\\ $$\\   $$\\ \n"
+    "$$  __$$\\ $$  __$$\\ $$  __$$\\ $$  __$$\\ \\$$\\ $$  |$$ |  $$ |\n"
+    "$$ |  $$ |$$ /  $$ |$$ |  \\__|$$ /  $$ | \\$$$$  / $$ |  $$ |\n"
+    "$$ |  $$ |$$ |  $$ |$$ |      $$ |  $$ | $$  $$<  $$ |  $$ |\n"
+    "$$$$$$$  |$$$$$$$  |$$ |      \\$$$$$$  |$$  /\\$$\\ \\$$$$$$$ |\n"
+    "\\_______/ $$  ____/ \\__|       \\______/ \\__/  \\__| \\____$$ |\n"
+    "          $$ |                                    $$\\   $$ |\n"
+    "          $$ |                                    \\$$$$$$  |\n"
+    "          \\__|                                     \\______/\n");
+    printf("\033[0m\n");
+}
+
 void parse_args(const int argc, char ** argv, struct socks5args * args) {
+    print_logo();
+
     memset(args, 0, sizeof(*args));
 
     args->socks_addr = NULL;
diff --git a/src/client.c b/src/client.c
index 41e9945..57bb211 100644
--- a/src/client.c
+++ b/src/client.c
@@ -431,7 +431,7 @@ int main(int argc, char **argv) {
     if (address != NULL) {
         if (inet_pton(AF_INET6, address, buf)) {
             domain = AF_INET6;
-        } else if (!inet_pton(AF_INET, address, buf)) { 
+        } else if (inet_pton(AF_INET, address, buf) <= 0) { 
             err_msg = "Incorrect network address";
             goto finally;
         }
@@ -527,7 +527,11 @@ finally:
         free(recv_buffer);
     }
     if (err_msg) {
-        perror(err_msg);
+        if (errno == 0) {
+            fprintf(stderr, "%s\n", err_msg);
+        } else {
+            perror(err_msg);
+        }
         ret = EXIT_FAILURE;
     }
 
diff --git a/src/server.c b/src/server.c
index 7767007..71761c6 100644
--- a/src/server.c
+++ b/src/server.c
@@ -34,33 +34,18 @@ static void sigterm_handler(const int signal) {
 static struct socks5args * args;
 uint64_t config_token;
 
-int main(int argc, char **argv) {
+int main(int argc, char ** argv) {
     char * token = getenv("BPROXY_TOKEN");
     if (token != NULL) {
         config_token = strtoul(token, NULL, 16);
     }
     else {
-        fprintf(stderr, "No token defined\n");
+        fprintf(stderr, "No token found. Please see README.md\n");
         exit(EXIT_FAILURE);
     }
     args = malloc(sizeof(struct socks5args));
     parse_args(argc, argv, args);
 
-    printf("\033[0;36m");
-    printf("$$\\\n"                                                         
-    "$$ |\n"                                                        
-    "$$ |\n"                                                        
-    "$$$$$$$\\   $$$$$$\\   $$$$$$\\   $$$$$$\\  $$\\   $$\\ $$\\   $$\\ \n"
-    "$$  __$$\\ $$  __$$\\ $$  __$$\\ $$  __$$\\ \\$$\\ $$  |$$ |  $$ |\n"
-    "$$ |  $$ |$$ /  $$ |$$ |  \\__|$$ /  $$ | \\$$$$  / $$ |  $$ |\n"
-    "$$ |  $$ |$$ |  $$ |$$ |      $$ |  $$ | $$  $$<  $$ |  $$ |\n"
-    "$$$$$$$  |$$$$$$$  |$$ |      \\$$$$$$  |$$  /\\$$\\ \\$$$$$$$ |\n"
-    "\\_______/ $$  ____/ \\__|       \\______/ \\__/  \\__| \\____$$ |\n"
-    "          $$ |                                    $$\\   $$ |\n"
-    "          $$ |                                    \\$$$$$$  |\n"
-    "          \\__|                                     \\______/\n\n");
-    printf("\033[0m");
-
     close(STDIN_FILENO);
 
     const char *err_msg = NULL;
@@ -68,10 +53,10 @@ int main(int argc, char **argv) {
     fd_selector selector = NULL;
     struct config * config_ret = NULL;
     struct config * config_ret_ipv6 = NULL;
-
-    // ------
-    // TCP
-    // ------
+    int server = -1;
+    int server_ipv6 = -1;
+    int udp_server = -1;
+    int udp_server_ipv6 = -1;
 
     unsigned char buf[sizeof(struct in6_addr)];
     int domain = -1;
@@ -80,11 +65,13 @@ int main(int argc, char **argv) {
             domain = AF_INET;
         } else if (inet_pton(AF_INET6, args->socks_addr, buf)) {
             domain = AF_INET6;
+        } else {
+            err_msg = "Incorrect network address";
+            goto finally;
         }
     }
 
     struct sockaddr_in addr;
-    int server;
     if (domain == AF_INET || domain == -1) {
         memset(&addr, 0, sizeof(addr));
         addr.sin_family = AF_INET;
@@ -123,7 +110,6 @@ int main(int argc, char **argv) {
     }
 
     struct sockaddr_in6 tcp_addr_ipv6;
-    int server_ipv6;
     if (domain == AF_INET6 || domain == -1) {
         memset(&tcp_addr_ipv6, 0, sizeof(tcp_addr_ipv6));
         tcp_addr_ipv6.sin6_family = AF_INET6;
@@ -162,21 +148,20 @@ int main(int argc, char **argv) {
         }
     }
 
-    // ------
-    // UDP
-    // ------
-
     int domain_udp = -1;
+    memset(&buf, 0, sizeof(buf));
     if (args->mng_addr != NULL) {
         if (inet_pton(AF_INET, args->mng_addr, buf)) { 
             domain_udp = AF_INET;
         } else if (inet_pton(AF_INET6, args->mng_addr, buf)) {
             domain_udp = AF_INET6;
+        } else {
+            err_msg = "Incorrect network address";
+            goto finally;
         }
     }
 
     struct sockaddr_in udp_addr;
-    int udp_server;
     if (domain_udp == AF_INET || domain_udp == -1) {
         memset(&udp_addr, 0, sizeof(udp_addr));
         udp_addr.sin_family = AF_INET;
@@ -224,7 +209,6 @@ int main(int argc, char **argv) {
     }
 
     struct sockaddr_in6 udp_addr_ipv6;
-    int udp_server_ipv6;
     if (domain_udp == AF_INET6 || domain_udp == -1) {
         memset(&udp_addr_ipv6, 0, sizeof(udp_addr_ipv6));
         udp_addr_ipv6.sin6_family = AF_INET6;
@@ -267,7 +251,7 @@ int main(int argc, char **argv) {
             err_msg = "Malloc failed";
             goto finally;
         }
-        memset(config_ret_ipv6, 0x00, sizeof(*config_ret));
+        memset(config_ret_ipv6, 0x00, sizeof(*config_ret_ipv6));
         buffer_init(&config_ret_ipv6->read_buffer, N(config_ret_ipv6->raw_buff_a), config_ret_ipv6->raw_buff_a);
         buffer_init(&config_ret_ipv6->write_buffer, N(config_ret_ipv6->raw_buff_b), config_ret_ipv6->raw_buff_b);
     }
@@ -383,7 +367,11 @@ finally:
         fprintf(stderr, "%s: %s\n", (err_msg == NULL) ? "": err_msg, ss == SELECTOR_IO ? strerror(errno) : selector_error(ss));
         ret = 2;
     } else if (err_msg) {
-        perror(err_msg);
+        if (errno == 0) {
+            fprintf(stderr, "%s\n", err_msg);
+        } else {
+            perror(err_msg);
+        }
         ret = 1;
     }
     if (selector != NULL) {
@@ -399,10 +387,10 @@ finally:
     if (server_ipv6 >= 0) {
         close(server_ipv6);
     }
-    if (udp_server > 0) {
+    if (udp_server >= 0) {
         close(udp_server);
     }
-    if (udp_server_ipv6 > 0) {
+    if (udp_server_ipv6 >= 0) {
         close(udp_server);
     }
     return ret;
diff --git a/src/socks5nio.c b/src/socks5nio.c
index faf62a3..126b187 100644
--- a/src/socks5nio.c
+++ b/src/socks5nio.c
@@ -276,6 +276,7 @@ socks5_destroy_(struct socks5 * s) {
     }
     if (s->username != NULL) {
         free(s->username);
+        s->username = 0;
     }
     free(s);
 }
@@ -291,6 +292,7 @@ socks5_destroy(struct socks5 * s) {
             parsers_destroy(s);
             if (s->username != NULL) {
                 free(s->username);
+                s->username = 0;
             }
             if(s->origin_resolution != NULL) {
                 freeaddrinfo(s->origin_resolution);
@@ -934,7 +936,7 @@ void log_request_access(enum socks_response_status status, const struct sockaddr
     if (username != NULL) {
         fprintf(file, "register=A user=%s %s status=%d\n", username, cbuff, status);
     } else {
-        fprintf(file, "register=A %s status=%d\n", cbuff, status);
+        fprintf(file, "register=A anon %s status=%d\n", cbuff, status);
     }
     fclose(file);
 }
@@ -958,7 +960,7 @@ void log_request_password(const struct sockaddr * origin_addr, char * username,
             break;
     }
     char * protocol;
-    if (port == 110) {
+    if (ntohs(port) == 110) {
         protocol = "POP3";
     }
     else {