diff --git a/tests/socks5.c b/tests/socks5.c index b3754b8..f63992c 100644 --- a/tests/socks5.c +++ b/tests/socks5.c @@ -1,341 +1,341 @@ /* socks5.c - Check the SOCKS5 client feature * Copyright (C) 2015 g10 Code GmbH * * This file is part of Assuan. * * Assuan is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Assuan is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_W32_SYSTEM # ifdef HAVE_WINSOCK2_H # include # endif # include #else /*!HAVE_W32_SYSTEM*/ # include # include # include #endif /*!HAVE_W32_SYSTEM*/ #include "../src/assuan.h" #include "common.h" /* M A I N */ int main (int argc, char **argv) { int last_argc = -1; gpg_error_t err; int only_v6 = 0; int only_v4 = 0; int use_tor = 0; int opt_have_proxy = 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; int lf_seen; gpgrt_init (); if (argc) { log_set_prefix (*argv); argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } 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" " --have-proxy Check whether the proxy is available\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")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = debug = 1; argc--; argv++; } else if (!strcmp (*argv, "-6") || !strcmp (*argv, "--inet6-only")) { only_v6 = 1; argc--; argv++; } else if (!strcmp (*argv, "-4") || !strcmp (*argv, "--inet4-only")) { only_v4 = 1; argc--; argv++; } else if (!strcmp (*argv, "--use-tor")) { use_tor = 1; argc--; argv++; } else if (!strcmp (*argv, "--disable-socks")) { disable_socks = 1; argc--; argv++; } else if (!strcmp (*argv, "--byname")) { opt_byname = 1; argc--; argv++; } else if (!strcmp (*argv, "--have-proxy")) { opt_have_proxy = 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); exit (1); } } if (argc != 2 && !opt_have_proxy) { fputs ("usage: socks5 HOST PORT\n", stderr); exit (1); } assuan_set_assuan_log_prefix (log_prefix); if (!assuan_check_version (ASSUAN_VERSION)) log_error ("assuan_check_version returned an error\n"); assuan_sock_init (); if (!disable_socks && assuan_sock_set_flag (ASSUAN_INVALID_FD, use_tor? "tor-mode":"socks", 1)) { err = gpg_error_from_syserror (); log_fatal ("setting %s mode failed: %s\n", use_tor? "TOR": "SOCKS", gpg_strerror (err)); } if (opt_have_proxy) { char *cred; if (user || pass) cred = xstrconcat (user?user:"", ":", pass, NULL); else cred = NULL; sock = assuan_sock_connect_byname (NULL, 0, 0, cred, use_tor? ASSUAN_SOCK_TOR : ASSUAN_SOCK_SOCKS); if (sock == ASSUAN_INVALID_FD) { err = gpg_error_from_syserror (); log_error ("SOCKS proxy is not available (%s)\n", gpg_strerror (err)); exit (1); } xfree (cred); assuan_sock_close (sock); if (verbose) log_info ("SOCKS proxy available\n"); exit (0); } else 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) + if (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 { #ifdef HAVE_GETADDRINFO 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); #else /*!HAVE_GETADDRINFO*/ (void)only_v4; (void)only_v6; fputs ("socks5: getaddrinfo not supported\n", stderr); exit (77); /* Skip test. */ #endif /*!HAVE_GETADDRINFO*/ } infp = es_fdopen_nc (sock, "rb"); if (!infp) { err = gpg_error_from_syserror (); assuan_sock_close (sock); log_fatal ("opening inbound stream failed: %s\n", gpg_strerror (err)); } outfp = es_fdopen (sock, "wb"); if (!outfp) { err = gpg_error_from_syserror (); es_fclose (infp); assuan_sock_close (sock); log_fatal ("opening outbound stream failed: %s\n", gpg_strerror (err)); } es_fputs ("GET / HTTP/1.0\r\n\r\n", outfp); if (es_fflush (outfp)) { err = gpg_error_from_syserror (); log_error ("es_fflush failed: %s\n", gpg_strerror (err)); } lf_seen = 0; while ((c = es_fgetc (infp)) != EOF) { if (c == '\r') continue; putchar (c); if (c == '\n') { if (lf_seen) break; lf_seen = 1; } else lf_seen = 0; } if (es_ferror (infp)) { err = gpg_error_from_syserror (); log_error ("es_fgetc failed: %s\n", gpg_strerror (err)); } es_fclose (infp); es_fclose (outfp); return errorcount ? 1 : 0; }