From 4061ac57ca84a1e0ed779096897a160d49b50c03 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 26 Oct 2015 14:35:41 +0100 Subject: Support hostname based SOCKS5 connection. * src/assuan.h.in (ASSUAN_SOCK_SOCKS): New. (ASSUAN_SOCK_TOR): New. (assuan_sock_connect_byname): New. * src/libassuan.def, src/libassuan.vers: Add that function. * src/assuan-socket.c (socks5_connect): Add args socksport, credentials, hostname, and hostport. Implement user/password authentication and domainname address type. Change callers accordingly. (_assuan_sock_connect_byname): New. (assuan_sock_connect_byname): New. * tests/socks5.c (main): Add options --byname, --user, and --pass. -- The assuan_sock_connect_byname may eventually be extended to work without Tor or SOCKS by using getaddrinfo. Or we move that all to libgpgrt (aka libgpg-error). Signed-off-by: Werner Koch --- tests/socks5.c | 183 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 64 deletions(-) (limited to 'tests') diff --git a/tests/socks5.c b/tests/socks5.c index c179108..7aa2b71 100644 --- a/tests/socks5.c +++ b/tests/socks5.c @@ -63,6 +63,9 @@ main (int argc, char **argv) int only_v4 = 0; int use_tor = 0; int disable_socks = 0; + int opt_byname = 0; + const char *user = NULL; + const char *pass = NULL; assuan_fd_t sock = ASSUAN_INVALID_FD; estream_t infp, outfp; int c; @@ -83,15 +86,18 @@ main (int argc, char **argv) else if (!strcmp (*argv, "--help")) { puts ( -"usage: ./socks5 [options] HOST PORT\n" -"\n" -"Options:\n" -" --verbose Show what is going on\n" -" --use-tor Use port 9050 instead of 1080\n" -" --inet6-only Use only IPv6\n" -" --inet4-only Use only IPv4\n" -" --disable-socks Connect w/o SOCKS\n" -); + "usage: ./socks5 [options] HOST PORT\n" + "\n" + "Options:\n" + " --verbose Show what is going on\n" + " --use-tor Use port 9050 instead of 1080\n" + " --inet6-only Use only IPv6\n" + " --inet4-only Use only IPv4\n" + " --disable-socks Connect w/o SOCKS\n" + " --byname Use assuan_sock_connect_byname\n" + " --user STRING Use STRING as user for authentication\n" + " --pass STRING Use STRING as password for authentication\n" + ); exit (0); } if (!strcmp (*argv, "--verbose")) @@ -124,6 +130,29 @@ main (int argc, char **argv) disable_socks = 1; argc--; argv++; } + else if (!strcmp (*argv, "--byname")) + { + opt_byname = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--user")) + { + argc--; argv++; + if (argc) + { + user = *argv; + argc--; argv++; + } + } + else if (!strcmp (*argv, "--pass")) + { + argc--; argv++; + if (argc) + { + pass = *argv; + argc--; argv++; + } + } else if (!strncmp (*argv, "--", 2)) { log_error ("unknown option '%s'\n", *argv); @@ -153,60 +182,86 @@ main (int argc, char **argv) use_tor? "TOR": "SOCKS", gpg_strerror (err)); } - { - struct addrinfo hints, *res, *ai; - int ret; - int anyok = 0; - - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; - ret = getaddrinfo (argv[0], argv[1], &hints, &res); - if (ret) - { - log_error ("error resolving '%s': %s\n", argv[0], gai_strerror (ret)); + if (opt_byname) + { + unsigned short port; + char *cred; + + if (user || pass) + cred = xstrconcat (user?user:"", ":", pass, NULL); + else + cred = NULL; + + port = strtoul (argv[1], NULL, 10); + if (port < 0 || port > 65535) + log_fatal ("port number out of range\n"); + + sock = assuan_sock_connect_byname (argv[0], port, 0, cred, + ASSUAN_SOCK_TOR); + if (sock == ASSUAN_INVALID_FD) + { + err = gpg_error_from_syserror (); + log_error ("assuan_sock_connect_byname (%s) failed: %s\n", + argv[0], gpg_strerror (err)); + exit (1); + } + xfree (cred); + } + else + { + struct addrinfo hints, *res, *ai; + int ret; + int anyok = 0; + + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + ret = getaddrinfo (argv[0], argv[1], &hints, &res); + if (ret) + { + log_error ("error resolving '%s': %s\n", argv[0], gai_strerror (ret)); + exit (1); + } + + for (ai = res; ai; ai = ai->ai_next) + { + if (ai->ai_family == AF_INET && only_v6) + continue; + if (ai->ai_family == AF_INET6 && only_v4) + continue; + + if (sock != ASSUAN_INVALID_FD) + assuan_sock_close (sock); + sock = assuan_sock_new (ai->ai_family, ai->ai_socktype, + ai->ai_protocol); + if (sock == ASSUAN_INVALID_FD) + { + err = gpg_error_from_syserror (); + log_error ("error creating socket: %s\n", gpg_strerror (err)); + freeaddrinfo (res); + exit (1); + } + + if (assuan_sock_connect (sock, ai->ai_addr, ai->ai_addrlen)) + { + err = gpg_error_from_syserror (); + log_error ("assuan_sock_connect (%s) failed: %s\n", + ai->ai_family == AF_INET6? "v6" : + ai->ai_family == AF_INET ? "v4" : "?", + gpg_strerror (err)); + } + else + { + log_info ("assuan_sock_connect succeeded (%s)\n", + ai->ai_family == AF_INET6? "v6" : + ai->ai_family == AF_INET ? "v4" : "?"); + anyok = 1; + break; + } + } + freeaddrinfo (res); + if (!anyok) exit (1); - } - - for (ai = res; ai; ai = ai->ai_next) - { - if (ai->ai_family == AF_INET && only_v6) - continue; - if (ai->ai_family == AF_INET6 && only_v4) - continue; - - if (sock != ASSUAN_INVALID_FD) - assuan_sock_close (sock); - sock = assuan_sock_new (ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - if (sock == ASSUAN_INVALID_FD) - { - err = gpg_error_from_syserror (); - log_error ("error creating socket: %s\n", gpg_strerror (err)); - freeaddrinfo (res); - exit (1); - } - - if (assuan_sock_connect (sock, ai->ai_addr, ai->ai_addrlen)) - { - err = gpg_error_from_syserror (); - log_error ("assuan_sock_connect (%s) failed: %s\n", - ai->ai_family == AF_INET6? "v6" : - ai->ai_family == AF_INET ? "v4" : "?", - gpg_strerror (err)); - } - else - { - log_info ("assuan_sock_connect succeeded (%d)\n", - ai->ai_family == AF_INET6? "v6" : - ai->ai_family == AF_INET ? "v4" : "?"); - anyok = 1; - break; - } - } - freeaddrinfo (res); - if (!anyok) - exit (1); - } + } infp = es_fdopen_nc (sock, "rb"); if (!infp) @@ -220,8 +275,8 @@ main (int argc, char **argv) { err = gpg_error_from_syserror (); es_fclose (infp); - assuan_sock_close (sock); - log_fatal ("opening outbound stream failed: %s\n", gpg_strerror (err)); + assuan_sock_close (sock); + log_fatal ("opening outbound stream failed: %s\n", gpg_strerror (err)); } es_fputs ("HEAD / HTTP/1.0\r\n\r\n", outfp); -- cgit v1.2.1