Ticket #13816: socks5-3.0.6.patch

File socks5-3.0.6.patch, 12.1 KB (added by eric-macosforge@…, 16 years ago)

Patch to privoxy 3.0.6 to add SOCKS 5 support

  • config

    diff -r 6ce92f2e919b config
    a b buffer-limit 4096 
    991991#
    992992
    993993#
    994 #  5.2. forward-socks4 and forward-socks4a
     994#  5.2. forward-socks4, forward-socks4a and forward-socks5
    995995#  =======================================
    996996#
    997997#  Specifies:
    buffer-limit 4096 
    10231023#      Multiple lines are OK, they are checked in sequence, and the
    10241024#      last match wins.
    10251025#
    1026 #      The difference between forward-socks4 and forward-socks4a
    1027 #      is that in the SOCKS 4A protocol, the DNS resolution of the
    1028 #      target hostname happens on the SOCKS server, while in SOCKS 4
    1029 #      it happens locally.
     1026
     1027#      The difference between forward-socks4 and either
     1028#      forward-socks4a or forward-socks5 is that in the SOCKS 4A and
     1029#      SOCKS 5 protocols, the DNS resolution of the target hostname
     1030#      happens on the SOCKS server, while in SOCKS 4 it happens
     1031#      locally.
    10301032#
    10311033#      If http_parent is ".", then requests are not forwarded to another
    10321034#      HTTP proxy but are made (HTTP-wise) directly to the web servers,
    buffer-limit 4096 
    10461048#      HTTP parent looks like this:
    10471049
    10481050#        forward-socks4   /               socks-gw.example.com:1080  .
     1051#
     1052#      ssh dynamic forwarding can handle either SOCKS 4 or SOCKS 5
     1053#      requests.  But name lookups on the server can only be done with
     1054#      SOCKS 5.  To chain Privoxy and ssh dynamic forwarding using
     1055#      SOCKS5 when they are both running on the same system, you
     1056#      should use the rule:
     1057#
     1058#        forward-socks5             /     127.0.0.1:3129 .
     1059#
     1060#      This presumes, of course, that you've configured your ssh
     1061#      connection with 'DynamicForward 3129'.
    10491062#
    10501063#      To chain Privoxy and Tor, both running on the same system,
    10511064#      you should use the rule:
  • gateway.c

    diff -r 6ce92f2e919b gateway.c
    a b static jb_socket socks4_connect(const st 
    161161                                int target_port,
    162162                                struct client_state *csp);
    163163
     164static jb_socket socks5_connect(const struct forward_spec * fwd,
     165                                const char * target_host,
     166                                int target_port,
     167                                struct client_state *csp);
     168
    164169
    165170#define SOCKS_REQUEST_GRANTED          90
    166171#define SOCKS_REQUEST_REJECT           91
    167172#define SOCKS_REQUEST_IDENT_FAILED     92
    168173#define SOCKS_REQUEST_IDENT_CONFLICT   93
     174#define SOCKS5_REQUEST_GRANTED             0
     175#define SOCKS5_REQUEST_FAILED              1
     176#define SOCKS5_REQUEST_DENIED              2
     177#define SOCKS5_REQUEST_NETWORK_UNREACHABLE 3
     178#define SOCKS5_REQUEST_HOST_UNREACHABLE    4
     179#define SOCKS5_REQUEST_CONNECTION_REFUSEDD 5
     180#define SOCKS5_REQUEST_TTL_EXPIRED         6
     181#define SOCKS5_REQUEST_PROTOCOL_ERROR      7
     182#define SOCKS5_REQUEST_BAD_ADDRESS_TYPE    8
    169183
    170184/* structure of a socks client operation */
    171185struct socks_op {
    jb_socket forwarded_connect(const struct 
    233247      case SOCKS_4:
    234248      case SOCKS_4A:
    235249         return (socks4_connect(fwd, dest_host, dest_port, csp));
     250
     251      case SOCKS_5:
     252         return (socks5_connect(fwd, dest_host, dest_port, csp));
    236253
    237254      default:
    238255         /* Should never get here */
    static jb_socket socks4_connect(const st 
    396413}
    397414
    398415
     416/*********************************************************************
     417 *
     418 * Function    :  socks4_connect
     419 *
     420 * Description :  Connect to the SOCKS server, and connect through
     421 *                it to the specified server.   This handles
     422 *                all the SOCKS negotiation, and returns a file
     423 *                descriptor for a socket which can be treated as a
     424 *                normal (non-SOCKS) socket.
     425 *
     426 * Parameters  :
     427 *          1  :  fwd = Specifies the SOCKS proxy to use.
     428 *          2  :  target_host = The final server to connect to.
     429 *          3  :  target_port = The final port to connect to.
     430 *          4  :  csp = Current client state (buffers, headers, etc...)
     431 *
     432 * Returns     :  JB_INVALID_SOCKET => failure, else a socket file descriptor.
     433 *
     434 *********************************************************************/
     435static jb_socket socks5_connect(const struct forward_spec * fwd,
     436                                const char * target_host,
     437                                int target_port,
     438                                struct client_state *csp)
     439{
     440   int err = 0;
     441   char cbuf[BUFFER_SIZE];
     442   char sbuf[BUFFER_SIZE];
     443   size_t client_pos = 0;
     444   ssize_t server_size = 0;
     445   size_t hostlen = 0;
     446   jb_socket sfd;
     447
     448   if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0'))
     449   {
     450      log_error(LOG_LEVEL_CONNECT, "socks5_connect: NULL gateway host specified");
     451      err = 1;
     452   }
     453
     454   if (fwd->gateway_port <= 0)
     455   {
     456      log_error(LOG_LEVEL_CONNECT, "socks5_connect: invalid gateway port specified");
     457      err = 1;
     458   }
     459
     460   hostlen = strlen(target_host);
     461   if (hostlen > 0xff)
     462   {
     463      log_error(LOG_LEVEL_CONNECT, "socks5_connect: target host name is longer than 255 characters.");
     464      err = 1;
     465   }
     466
     467   if (fwd->type != SOCKS_5)
     468   {
     469      /* Should never get here */
     470      log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
     471      err = 1;
     472   }
     473
     474   if (err)
     475   {
     476      errno = EINVAL;
     477      return(JB_INVALID_SOCKET);
     478   }
     479
     480   /* pass the request to the socks server */
     481   sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp);
     482
     483   if (sfd == JB_INVALID_SOCKET)
     484   {
     485      return(JB_INVALID_SOCKET);
     486   }
     487
     488   cbuf[client_pos++] = '\x05'; // Version
     489   cbuf[client_pos++] = '\x01'; // One authentication method supported
     490   cbuf[client_pos++] = '\x00'; // The no authentication authentication method
     491
     492   if (write_socket(sfd, cbuf, client_pos))
     493   {
     494      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation write failed...");
     495      close_socket(sfd);
     496      return(JB_INVALID_SOCKET);
     497   }
     498
     499   if (read_socket(sfd, sbuf, sizeof(sbuf)) != 2)
     500   {
     501      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation read failed...");
     502      err = 1;
     503   }
     504
     505   if (!err && (sbuf[0] != '\x05'))
     506   {
     507      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol version error");
     508      err = 1;
     509   }
     510
     511   if (!err && (sbuf[1] == '\xff'))
     512   {
     513      log_error(LOG_LEVEL_CONNECT, "SOCKS5 authentication required");
     514      err = 1;
     515   }
     516
     517   if (!err && (sbuf[1] != '\x00'))
     518   {
     519      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error");
     520      err = 1;
     521   }
     522
     523   if (err)
     524   {
     525      close_socket(sfd);
     526      errno = EINVAL;
     527      return(JB_INVALID_SOCKET);
     528   }
     529
     530   client_pos = 0;
     531   cbuf[client_pos++] = '\x05'; // Version
     532   cbuf[client_pos++] = '\x01'; // TCP connect
     533   cbuf[client_pos++] = '\x00'; // Reserved, must be 0x00
     534   cbuf[client_pos++] = '\x03'; // Address is domain name
     535   cbuf[client_pos++] = (char)(hostlen & 0xffu);
     536   strncpy(cbuf + client_pos, target_host, 0xffu);
     537   client_pos += (hostlen & 0xffu);
     538   cbuf[client_pos++] = (char)((target_port >> 8) & 0xffu);
     539   cbuf[client_pos++] = (char)((target_port     ) & 0xffu);
     540
     541   if (write_socket(sfd, cbuf, client_pos))
     542   {
     543      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation write failed...");
     544      close_socket(sfd);
     545      errno = EINVAL;
     546      return(JB_INVALID_SOCKET);
     547   }
     548
     549   server_size = read_socket(sfd, sbuf, sizeof(sbuf));
     550   if (server_size < 3)
     551   {
     552      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation read failed...");
     553      err = 1;
     554   }
     555
     556   if (!err && (sbuf[0] != '\x05'))
     557   {
     558      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol version error");
     559      err = 1;
     560   }
     561
     562   if (!err && (sbuf[2] != '\x00'))
     563   {
     564      log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error");
     565      err = 1;
     566   }
     567
     568   if (!err)
     569   {
     570      switch (sbuf[1]) {
     571       case SOCKS5_REQUEST_GRANTED:
     572         return(sfd);
     573         break;
     574       case SOCKS5_REQUEST_FAILED:
     575         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request failed");
     576         break;
     577       case SOCKS5_REQUEST_DENIED:
     578         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request denied");
     579         break;
     580       case SOCKS5_REQUEST_NETWORK_UNREACHABLE:
     581         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - network unreachable");
     582         break;
     583       case SOCKS5_REQUEST_HOST_UNREACHABLE:
     584         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - host unreachable");
     585         break;
     586       case SOCKS5_REQUEST_CONNECTION_REFUSEDD:
     587         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - connection refused");
     588         break;
     589       case SOCKS5_REQUEST_TTL_EXPIRED:
     590         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - TTL expired");
     591         break;
     592       case SOCKS5_REQUEST_PROTOCOL_ERROR:
     593         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - client protocol error");
     594         break;
     595       case SOCKS5_REQUEST_BAD_ADDRESS_TYPE:
     596         log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - domain names unsupported");
     597         break;
     598       default:
     599         log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error");
     600         break;
     601      }
     602      err = 1;
     603   }
     604
     605   close_socket(sfd);
     606   errno = EINVAL;
     607   return(JB_INVALID_SOCKET);
     608}
     609
    399610/*
    400611  Local Variables:
    401612  tab-width: 3
  • loadcfg.c

    diff -r 6ce92f2e919b loadcfg.c
    a b static struct file_list *current_configf 
    465465#define hash_forward                      2029845ul /* "forward" */
    466466#define hash_forward_socks4            3963965521ul /* "forward-socks4" */
    467467#define hash_forward_socks4a           2639958518ul /* "forward-socks4a" */
     468#define hash_forward_socks5            3963965522ul /* "forward-socks5" */
    468469#define hash_forwarded_connect_retries  101465292ul /* "forwarded-connect-retries" */
    469470#define hash_jarfile                      2046641ul /* "jarfile" */
    470471#define hash_listen_address            1255650842ul /* "listen-address" */
    struct configuration_spec * load_config( 
    690691      struct forward_spec *cur_fwd;
    691692      int vec_count;
    692693      char *vec[3];
     694      unsigned long int directive_hash = 0ul;
    693695
    694696      strcpy(tmp, buf);
    695697
    struct configuration_spec * load_config( 
    730732      savearg(cmd, arg, config);
    731733
    732734
    733       switch( hash_string( cmd ) )
     735      directive_hash = hash_string( cmd );
     736      switch( directive_hash )
    734737      {
    735738/* *************************************************************************
    736739 * actionsfile actions-file-name
    struct configuration_spec * load_config( 
    10891092 * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port])
    10901093 * *************************************************************************/
    10911094         case hash_forward_socks4a:
     1095         case hash_forward_socks5:
    10921096            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
    10931097
    10941098            if (vec_count != 3)
    struct configuration_spec * load_config( 
    11101114               continue;
    11111115            }
    11121116
    1113             cur_fwd->type = SOCKS_4A;
     1117            if (directive_hash == hash_forward_socks4a) {
     1118               cur_fwd->type = SOCKS_4A;
     1119            } else {
     1120               cur_fwd->type = SOCKS_5;
     1121            }
    11141122
    11151123            /* Save the URL pattern */
    11161124            if (create_url_spec(cur_fwd->url, vec[0]))
  • project.h

    diff -r 6ce92f2e919b project.h
    a b struct block_spec 
    13261326#define SOCKS_NONE    0    /**< Don't use a SOCKS server               */
    13271327#define SOCKS_4      40    /**< original SOCKS 4 protocol              */
    13281328#define SOCKS_4A     41    /**< as modified for hosts w/o external DNS */
     1329#define SOCKS_5      50    /**< as modified for hosts w/o external DNS */
    13291330
    13301331
    13311332/**
    struct forward_spec 
    13361337   /** URL pattern that this forward_spec is for. */
    13371338   struct url_spec url[1];
    13381339
    1339    /** Connection type.  Must be SOCKS_NONE, SOCKS_4, or SOCKS_4A. */
     1340   /** Connection type.  Must be SOCKS_NONE, SOCKS_4, SOCKS_4A or SOCKS_5. */
    13401341   int   type;
    13411342
    13421343   /** SOCKS server hostname.  Only valid if "type" is SOCKS_4 or SOCKS_4A. */