LCOV - code coverage report
Current view: top level - tests - socks5.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 136 0.0 %
Date: 2015-11-05 17:06:03 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* socks5.c - Check the SOCKS5 client feature
       2             :  * Copyright (C) 2015 g10 Code GmbH
       3             :  *
       4             :  * This file is part of Assuan.
       5             :  *
       6             :  * Assuan is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Assuan is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #ifdef HAVE_CONFIG_H
      21             : #include <config.h>
      22             : #endif
      23             : 
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <string.h>
      27             : #include <assert.h>
      28             : #ifdef HAVE_W32_SYSTEM
      29             : # ifdef HAVE_WINSOCK2_H
      30             : #  include <winsock2.h>
      31             : # endif
      32             : # include <windows.h>
      33             : #else /*!HAVE_W32_SYSTEM*/
      34             : # include <sys/types.h>
      35             : # include <sys/socket.h>
      36             : # include <netdb.h>
      37             : #endif /*!HAVE_W32_SYSTEM*/
      38             : 
      39             : #include "../src/assuan.h"
      40             : #include "common.h"
      41             : 
      42             : #ifndef HAVE_GETADDRINFO
      43             : int
      44             : main (void)
      45             : {
      46             :   fputs ("socks5: getaddrinfo not supported\n", stderr);
      47             :   return 77; /* Skip test.  */
      48             : }
      49             : #else /* HAVE_GETADDRINFO */
      50             : 
      51             : 
      52             : /*
      53             : 
      54             :      M A I N
      55             : 
      56             : */
      57             : int
      58           0 : main (int argc, char **argv)
      59             : {
      60           0 :   int last_argc = -1;
      61             :   gpg_error_t err;
      62           0 :   int only_v6 = 0;
      63           0 :   int only_v4 = 0;
      64           0 :   int use_tor = 0;
      65           0 :   int disable_socks = 0;
      66           0 :   int opt_byname = 0;
      67           0 :   const char *user = NULL;
      68           0 :   const char *pass = NULL;
      69           0 :   assuan_fd_t sock = ASSUAN_INVALID_FD;
      70             :   estream_t infp, outfp;
      71             :   int c;
      72             :   int lf_seen;
      73             : 
      74           0 :   if (argc)
      75             :     {
      76           0 :       log_set_prefix (*argv);
      77           0 :       argc--; argv++;
      78             :     }
      79           0 :   while (argc && last_argc != argc )
      80             :     {
      81           0 :       last_argc = argc;
      82           0 :       if (!strcmp (*argv, "--"))
      83             :         {
      84           0 :           argc--; argv++;
      85           0 :           break;
      86             :         }
      87           0 :       else if (!strcmp (*argv, "--help"))
      88             :         {
      89           0 :           puts (
      90             :                 "usage: ./socks5 [options] HOST PORT\n"
      91             :                 "\n"
      92             :                 "Options:\n"
      93             :                 "  --verbose        Show what is going on\n"
      94             :                 "  --use-tor        Use port 9050 instead of 1080\n"
      95             :                 "  --inet6-only     Use only IPv6\n"
      96             :                 "  --inet4-only     Use only IPv4\n"
      97             :                 "  --disable-socks  Connect w/o SOCKS\n"
      98             :                 "  --byname         Use assuan_sock_connect_byname\n"
      99             :                 "  --user STRING    Use STRING as user for authentication\n"
     100             :                 "  --pass STRING    Use STRING as password for authentication\n"
     101             :                 );
     102           0 :           exit (0);
     103             :         }
     104           0 :       if (!strcmp (*argv, "--verbose"))
     105             :         {
     106           0 :           verbose = 1;
     107           0 :           argc--; argv++;
     108             :         }
     109           0 :       else if (!strcmp (*argv, "--debug"))
     110             :         {
     111           0 :           verbose = debug = 1;
     112           0 :           argc--; argv++;
     113             :         }
     114           0 :       else if (!strcmp (*argv, "-6") || !strcmp (*argv, "--inet6-only"))
     115             :         {
     116           0 :           only_v6 = 1;
     117           0 :           argc--; argv++;
     118             :         }
     119           0 :       else if (!strcmp (*argv, "-4") || !strcmp (*argv, "--inet4-only"))
     120             :         {
     121           0 :           only_v4 = 1;
     122           0 :           argc--; argv++;
     123             :         }
     124           0 :       else if (!strcmp (*argv, "--use-tor"))
     125             :         {
     126           0 :           use_tor = 1;
     127           0 :           argc--; argv++;
     128             :         }
     129           0 :       else if (!strcmp (*argv, "--disable-socks"))
     130             :         {
     131           0 :           disable_socks = 1;
     132           0 :           argc--; argv++;
     133             :         }
     134           0 :       else if (!strcmp (*argv, "--byname"))
     135             :         {
     136           0 :           opt_byname = 1;
     137           0 :           argc--; argv++;
     138             :         }
     139           0 :       else if (!strcmp (*argv, "--user"))
     140             :         {
     141           0 :           argc--; argv++;
     142           0 :           if (argc)
     143             :             {
     144           0 :               user = *argv;
     145           0 :               argc--; argv++;
     146             :             }
     147             :         }
     148           0 :       else if (!strcmp (*argv, "--pass"))
     149             :         {
     150           0 :           argc--; argv++;
     151           0 :           if (argc)
     152             :             {
     153           0 :               pass = *argv;
     154           0 :               argc--; argv++;
     155             :             }
     156             :         }
     157           0 :       else if (!strncmp (*argv, "--", 2))
     158             :         {
     159           0 :           log_error ("unknown option '%s'\n", *argv);
     160           0 :           exit (1);
     161             :         }
     162             :     }
     163             : 
     164           0 :   if (argc != 2)
     165             :     {
     166           0 :       fputs ("usage: socks5 HOST PORT\n", stderr);
     167           0 :       exit (1);
     168             :     }
     169             : 
     170           0 :   assuan_set_assuan_log_prefix (log_prefix);
     171             : 
     172           0 :   if (!assuan_check_version (ASSUAN_VERSION))
     173           0 :     log_error ("assuan_check_version returned an error\n");
     174             : 
     175           0 :   assuan_sock_init ();
     176             : 
     177           0 :   if (!disable_socks
     178           0 :       && assuan_sock_set_flag (ASSUAN_INVALID_FD,
     179             :                                use_tor? "tor-mode":"socks", 1))
     180             :     {
     181           0 :       err = gpg_error_from_syserror ();
     182           0 :       log_fatal ("setting %s mode failed: %s\n",
     183             :                  use_tor? "TOR": "SOCKS", gpg_strerror (err));
     184             :     }
     185             : 
     186           0 :   if (opt_byname)
     187             :     {
     188             :       unsigned short port;
     189             :       char *cred;
     190             : 
     191           0 :       if (user || pass)
     192           0 :         cred = xstrconcat (user?user:"", ":", pass, NULL);
     193             :       else
     194           0 :         cred = NULL;
     195             : 
     196           0 :       port = strtoul (argv[1], NULL, 10);
     197             :       if (port < 0 || port > 65535)
     198             :         log_fatal ("port number out of range\n");
     199             : 
     200           0 :       sock = assuan_sock_connect_byname (argv[0], port, 0, cred,
     201             :                                          ASSUAN_SOCK_TOR);
     202           0 :       if (sock == ASSUAN_INVALID_FD)
     203             :         {
     204           0 :           err = gpg_error_from_syserror ();
     205           0 :           log_error ("assuan_sock_connect_byname (%s) failed: %s\n",
     206             :                      argv[0], gpg_strerror (err));
     207           0 :           exit (1);
     208             :         }
     209           0 :       xfree (cred);
     210             :     }
     211             :   else
     212             :     {
     213             :       struct addrinfo hints, *res, *ai;
     214             :       int ret;
     215           0 :       int anyok = 0;
     216             : 
     217           0 :       memset (&hints, 0, sizeof (hints));
     218           0 :       hints.ai_socktype = SOCK_STREAM;
     219           0 :       ret = getaddrinfo (argv[0], argv[1], &hints, &res);
     220           0 :       if (ret)
     221             :         {
     222           0 :           log_error ("error resolving '%s': %s\n", argv[0], gai_strerror (ret));
     223           0 :           exit (1);
     224             :         }
     225             : 
     226           0 :       for (ai = res; ai; ai = ai->ai_next)
     227             :         {
     228           0 :           if (ai->ai_family == AF_INET && only_v6)
     229           0 :             continue;
     230           0 :           if (ai->ai_family == AF_INET6 && only_v4)
     231           0 :             continue;
     232             : 
     233           0 :           if (sock != ASSUAN_INVALID_FD)
     234           0 :             assuan_sock_close (sock);
     235           0 :           sock = assuan_sock_new (ai->ai_family, ai->ai_socktype,
     236             :                                   ai->ai_protocol);
     237           0 :           if (sock == ASSUAN_INVALID_FD)
     238             :             {
     239           0 :               err = gpg_error_from_syserror ();
     240           0 :               log_error ("error creating socket: %s\n", gpg_strerror (err));
     241           0 :               freeaddrinfo (res);
     242           0 :               exit (1);
     243             :             }
     244             : 
     245           0 :           if (assuan_sock_connect (sock,  ai->ai_addr, ai->ai_addrlen))
     246             :             {
     247           0 :               err = gpg_error_from_syserror ();
     248           0 :               log_error ("assuan_sock_connect (%s) failed: %s\n",
     249           0 :                          ai->ai_family == AF_INET6? "v6" :
     250           0 :                          ai->ai_family == AF_INET ? "v4" : "?",
     251             :                          gpg_strerror (err));
     252             :             }
     253             :           else
     254             :             {
     255           0 :               log_info ("assuan_sock_connect succeeded (%s)\n",
     256           0 :                         ai->ai_family == AF_INET6? "v6" :
     257           0 :                         ai->ai_family == AF_INET ? "v4" : "?");
     258           0 :               anyok = 1;
     259           0 :               break;
     260             :             }
     261             :         }
     262           0 :       freeaddrinfo (res);
     263           0 :       if (!anyok)
     264           0 :         exit (1);
     265             :     }
     266             : 
     267           0 :   infp = es_fdopen_nc (sock, "rb");
     268           0 :   if (!infp)
     269             :     {
     270           0 :       err = gpg_error_from_syserror ();
     271           0 :       assuan_sock_close (sock);
     272           0 :       log_fatal ("opening inbound stream failed: %s\n", gpg_strerror (err));
     273             :     }
     274           0 :   outfp = es_fdopen (sock, "wb");
     275           0 :   if (!outfp)
     276             :     {
     277           0 :       err = gpg_error_from_syserror ();
     278           0 :       es_fclose (infp);
     279           0 :       assuan_sock_close (sock);
     280           0 :       log_fatal ("opening outbound stream failed: %s\n", gpg_strerror (err));
     281             :     }
     282             : 
     283           0 :   es_fputs ("GET / HTTP/1.0\r\n\r\n", outfp);
     284           0 :   es_fflush (outfp);
     285           0 :   lf_seen = 0;
     286           0 :   while ((c = es_fgetc (infp)) != EOF)
     287             :     {
     288           0 :       if (c == '\r')
     289           0 :         continue;
     290           0 :       putchar (c);
     291           0 :       if (c == '\n')
     292             :         {
     293           0 :           if (lf_seen)
     294           0 :             break;
     295           0 :           lf_seen = 1;
     296             :         }
     297             :       else
     298           0 :         lf_seen = 0;
     299             :     }
     300           0 :   es_fclose (infp);
     301           0 :   es_fclose (outfp);
     302             : 
     303           0 :   return errorcount ? 1 : 0;
     304             : }
     305             : #endif /*HAVE_GETADDRINFO*/

Generated by: LCOV version 1.11