changeset 608:a8fa7803284a

Change how proxy is specified on commandline.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 20 May 2014 04:35:24 +0300
parents c7b8e299c612
children b10d81ddfc55
files main.c
diffstat 1 files changed, 109 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/main.c	Tue May 20 04:34:36 2014 +0300
+++ b/main.c	Tue May 20 04:35:24 2014 +0300
@@ -120,9 +120,7 @@
     { 7, 'f', "force-site", "Force site (default: NN)", OPT_ARGREQ },
     { 8, 'd', "debug",      "Enable various debug features", OPT_NONE },
 
-    {10, '4', "socks4",     "SOCKS4 proxy server", OPT_ARGREQ },
-    {11, 'A', "socks4a",    "SOCKS4A proxy server", OPT_ARGREQ },
-    {12, 'P', "proxy-port", "Proxy port (default: 1080)", OPT_ARGREQ },
+    {10, 'P', "proxy",      "Set proxy data, see below for syntax", OPT_ARGREQ },
 
     {13, 'r', "room",       "Connect to room (main, pit)", OPT_ARGREQ },
 };
@@ -137,7 +135,18 @@
 
     th_args_help(stdout, optList, optListN);
 
-    printf("Supported rooms (for option '-r'):\n");
+    printf(
+    "\n"
+    "Supported proxy types are SOCKS 4/4A and SOCKS 5.\n"
+    "These can be set with the -P option as follows:\n"
+    "\n"
+    " -P <type>://[<userid>[:passwd]@]<host>[:<port>]\n"
+    "\n"
+    "Type can be socks4, socks4a or socks5. Only socks5\n"
+    "supports user/pass authentication.\n"
+    "\n"
+    "Supported rooms (for option '-r'):\n");
+
     for (i = 0; i < nn_room_data_n; i++)
     {
         printf("  %s  - %s (port %d)\n",
@@ -148,6 +157,100 @@
 }
 
 
+BOOL argSplitStr(const char *src, const char *at, char **res1, char **res2)
+{
+    char *pos, *tmp = th_strdup(src);
+
+    if (tmp != NULL && (pos = strstr(tmp, at)) != NULL)
+    {
+        *pos = 0;
+        pos += strlen(at);
+        *res1 = th_strdup_trim(tmp, TH_TRIM_BOTH);
+        *res2 = th_strdup_trim(pos, TH_TRIM_BOTH);
+        th_free(tmp);
+        return TRUE;
+    }
+    else
+    {
+        th_free(tmp);
+        return FALSE;
+    }
+}
+
+
+BOOL argHandleProxyURI(const char *uri)
+{
+    // Attempt to parse the proxy URI
+    BOOL ret = FALSE;
+    char *proto = NULL, *rest = NULL, *host = NULL,
+         *auth = NULL, *port = NULL;
+
+    if (!argSplitStr(uri, "://", &proto, &rest))
+    {
+        THERR("Malformed proxy URI, should be <type>://[<userid>[:passwd]@]<host>[:<port>]\n");
+        goto out;
+    }
+
+    // Validate proxy type
+    if (strcasecmp(proto, "socks4") == 0)
+        optProxyType = NN_PROXY_SOCKS4;
+    else
+    if (strcasecmp(proto, "socks4a") == 0)
+        optProxyType = NN_PROXY_SOCKS4A;
+    else
+    {
+        THERR("Invalid proxy type specified: '%s'\n", proto);
+        goto out;
+    }
+
+    // Does the URI contain anything else?
+    if (strlen(rest) == 0)
+    {
+        THERR("Malformed proxy URI, no host specified.\n");
+        goto out;
+    }
+
+    // Check for auth credentials
+    if (argSplitStr(rest, "@", &auth, &host))
+    {
+        if (strlen(auth) == 0)
+        {
+            THERR("Malformed proxy URI, zero length authentication credentials.\n");
+            goto out;
+        }
+
+        // Should have authentication credentials
+        if (!argSplitStr(auth, ":", &optProxyUserID, &optProxyPassword))
+            optProxyUserID = th_strdup(auth);
+    }
+    else
+        host = th_strdup(rest);
+
+    // Check if proxy port was specified
+    if (argSplitStr(host, ":", &optProxyServer, &port))
+        optProxyPort = atoi(port);
+    else
+        optProxyServer = th_strdup(host);
+
+    // Check what authentication type to use
+    if (optProxyType == NN_PROXY_SOCKS5 &&
+        optProxyUserID != NULL && optProxyPassword != NULL)
+        optProxyAuthType = NN_PROXY_AUTH_USER;
+    else
+        optProxyAuthType = NN_PROXY_AUTH_NONE;
+
+    ret = TRUE;
+
+out:
+    th_free(proto);
+    th_free(rest);
+    th_free(host);
+    th_free(auth);
+    th_free(port);
+
+    return ret;
+}
+
 BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
 {
     switch (optN)
@@ -195,17 +298,8 @@
 
 
     case 10:
-        optProxyServer = optArg;
-        optProxyType = NN_PROXY_SOCKS4;
-        break;
-
-    case 11:
-        optProxyServer = optArg;
-        optProxyType = NN_PROXY_SOCKS4A;
-        break;
-
-    case 12:
-        optProxyPort = atoi(optArg);
+        if (!argHandleProxyURI(optArg))
+            return FALSE;
         break;
 
     case 13: