Ticket #14293: patch-socks5.diff
File patch-socks5.diff, 11.7 KB (added by simon@…, 17 years ago) |
---|
-
config
diff -r 6ce92f2e919b config
1097 1097 # 1098 1098 # 1099 1099 # 1100 # 5.2. forward-socks4 and forward-socks4a1100 # 5.2. forward-socks4, forward-socks4a and forward-socks5 1101 1101 # 1102 1102 # Specifies: 1103 1103 # … … 1128 1128 # Multiple lines are OK, they are checked in sequence, and the 1129 1129 # last match wins. 1130 1130 # 1131 # The difference between forward-socks4 and forward-socks4a 1132 # is that in the SOCKS 4A protocol, the DNS resolution of the 1133 # target hostname happens on the SOCKS server, while in SOCKS 4 1134 # it happens locally. 1131 1132 # The difference between forward-socks4 and either 1133 # forward-socks4a or forward-socks5 is that in the SOCKS 4A and 1134 # SOCKS 5 protocols, the DNS resolution of the target hostname 1135 # happens on the SOCKS server, while in SOCKS 4 it happens 1136 # locally. 1135 1137 # 1136 1138 # If http_parent is ".", then requests are not forwarded to another 1137 1139 # HTTP proxy but are made (HTTP-wise) directly to the web servers, … … 1153 1155 # 1154 1156 # forward-socks4 / socks-gw.example.com:1080 . 1155 1157 # 1158 # ssh dynamic forwarding can handle either SOCKS 4 or SOCKS 5 1159 # requests. But name lookups on the server can only be done with 1160 # SOCKS 5. To chain Privoxy and ssh dynamic forwarding using 1161 # SOCKS5 when they are both running on the same system, you 1162 # should use the rule: 1163 # 1164 # forward-socks5 / 127.0.0.1:3129 . 1165 # 1166 # This presumes, of course, that you've configured your ssh 1167 # connection with 'DynamicForward 3129'. 1168 # 1156 1169 # 1157 1170 # To chain Privoxy and Tor, both running on the same system, 1158 1171 # you would use something like: -
gateway.c
diff -r 6ce92f2e919b gateway.c
176 176 int target_port, 177 177 struct client_state *csp); 178 178 179 static jb_socket socks5_connect(const struct forward_spec * fwd, 180 const char * target_host, 181 int target_port, 182 struct client_state *csp); 183 179 184 180 185 #define SOCKS_REQUEST_GRANTED 90 181 186 #define SOCKS_REQUEST_REJECT 91 182 187 #define SOCKS_REQUEST_IDENT_FAILED 92 183 188 #define SOCKS_REQUEST_IDENT_CONFLICT 93 189 #define SOCKS5_REQUEST_GRANTED 0 190 #define SOCKS5_REQUEST_FAILED 1 191 #define SOCKS5_REQUEST_DENIED 2 192 #define SOCKS5_REQUEST_NETWORK_UNREACHABLE 3 193 #define SOCKS5_REQUEST_HOST_UNREACHABLE 4 194 #define SOCKS5_REQUEST_CONNECTION_REFUSEDD 5 195 #define SOCKS5_REQUEST_TTL_EXPIRED 6 196 #define SOCKS5_REQUEST_PROTOCOL_ERROR 7 197 #define SOCKS5_REQUEST_BAD_ADDRESS_TYPE 8 184 198 185 199 /* structure of a socks client operation */ 186 200 struct socks_op { … … 250 264 case SOCKS_4A: 251 265 return (socks4_connect(fwd, dest_host, dest_port, csp)); 252 266 267 case SOCKS_5: 268 return (socks5_connect(fwd, dest_host, dest_port, csp)); 269 253 270 default: 254 271 /* Should never get here */ 255 272 log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type."); … … 454 471 } 455 472 456 473 474 /********************************************************************* 475 * 476 * Function : socks4_connect 477 * 478 * Description : Connect to the SOCKS server, and connect through 479 * it to the specified server. This handles 480 * all the SOCKS negotiation, and returns a file 481 * descriptor for a socket which can be treated as a 482 * normal (non-SOCKS) socket. 483 * 484 * Parameters : 485 * 1 : fwd = Specifies the SOCKS proxy to use. 486 * 2 : target_host = The final server to connect to. 487 * 3 : target_port = The final port to connect to. 488 * 4 : csp = Current client state (buffers, headers, etc...) 489 * 490 * Returns : JB_INVALID_SOCKET => failure, else a socket file descriptor. 491 * 492 *********************************************************************/ 493 static jb_socket socks5_connect(const struct forward_spec * fwd, 494 const char * target_host, 495 int target_port, 496 struct client_state *csp) 497 { 498 int err = 0; 499 char cbuf[BUFFER_SIZE]; 500 char sbuf[BUFFER_SIZE]; 501 size_t client_pos = 0; 502 ssize_t server_size = 0; 503 size_t hostlen = 0; 504 jb_socket sfd; 505 506 if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0')) 507 { 508 log_error(LOG_LEVEL_CONNECT, "socks5_connect: NULL gateway host specified"); 509 err = 1; 510 } 511 512 if (fwd->gateway_port <= 0) 513 { 514 log_error(LOG_LEVEL_CONNECT, "socks5_connect: invalid gateway port specified"); 515 err = 1; 516 } 517 518 hostlen = strlen(target_host); 519 if (hostlen > 0xff) 520 { 521 log_error(LOG_LEVEL_CONNECT, "socks5_connect: target host name is longer than 255 characters."); 522 err = 1; 523 } 524 525 if (fwd->type != SOCKS_5) 526 { 527 /* Should never get here */ 528 log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type."); 529 err = 1; 530 } 531 532 if (err) 533 { 534 errno = EINVAL; 535 return(JB_INVALID_SOCKET); 536 } 537 538 /* pass the request to the socks server */ 539 sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp); 540 541 if (sfd == JB_INVALID_SOCKET) 542 { 543 return(JB_INVALID_SOCKET); 544 } 545 546 cbuf[client_pos++] = '\x05'; // Version 547 cbuf[client_pos++] = '\x01'; // One authentication method supported 548 cbuf[client_pos++] = '\x00'; // The no authentication authentication method 549 550 if (write_socket(sfd, cbuf, client_pos)) 551 { 552 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation write failed..."); 553 close_socket(sfd); 554 return(JB_INVALID_SOCKET); 555 } 556 557 if (read_socket(sfd, sbuf, sizeof(sbuf)) != 2) 558 { 559 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation read failed..."); 560 err = 1; 561 } 562 563 if (!err && (sbuf[0] != '\x05')) 564 { 565 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol version error"); 566 err = 1; 567 } 568 569 if (!err && (sbuf[1] == '\xff')) 570 { 571 log_error(LOG_LEVEL_CONNECT, "SOCKS5 authentication required"); 572 err = 1; 573 } 574 575 if (!err && (sbuf[1] != '\x00')) 576 { 577 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error"); 578 err = 1; 579 } 580 581 if (err) 582 { 583 close_socket(sfd); 584 errno = EINVAL; 585 return(JB_INVALID_SOCKET); 586 } 587 588 client_pos = 0; 589 cbuf[client_pos++] = '\x05'; // Version 590 cbuf[client_pos++] = '\x01'; // TCP connect 591 cbuf[client_pos++] = '\x00'; // Reserved, must be 0x00 592 cbuf[client_pos++] = '\x03'; // Address is domain name 593 cbuf[client_pos++] = (char)(hostlen & 0xffu); 594 strncpy(cbuf + client_pos, target_host, 0xffu); 595 client_pos += (hostlen & 0xffu); 596 cbuf[client_pos++] = (char)((target_port >> 8) & 0xffu); 597 cbuf[client_pos++] = (char)((target_port ) & 0xffu); 598 599 if (write_socket(sfd, cbuf, client_pos)) 600 { 601 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation write failed..."); 602 close_socket(sfd); 603 errno = EINVAL; 604 return(JB_INVALID_SOCKET); 605 } 606 607 server_size = read_socket(sfd, sbuf, sizeof(sbuf)); 608 if (server_size < 3) 609 { 610 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation read failed..."); 611 err = 1; 612 } 613 614 if (!err && (sbuf[0] != '\x05')) 615 { 616 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol version error"); 617 err = 1; 618 } 619 620 if (!err && (sbuf[2] != '\x00')) 621 { 622 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error"); 623 err = 1; 624 } 625 626 if (!err) 627 { 628 switch (sbuf[1]) { 629 case SOCKS5_REQUEST_GRANTED: 630 return(sfd); 631 break; 632 case SOCKS5_REQUEST_FAILED: 633 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request failed"); 634 break; 635 case SOCKS5_REQUEST_DENIED: 636 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request denied"); 637 break; 638 case SOCKS5_REQUEST_NETWORK_UNREACHABLE: 639 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - network unreachable"); 640 break; 641 case SOCKS5_REQUEST_HOST_UNREACHABLE: 642 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - host unreachable"); 643 break; 644 case SOCKS5_REQUEST_CONNECTION_REFUSEDD: 645 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - connection refused"); 646 break; 647 case SOCKS5_REQUEST_TTL_EXPIRED: 648 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - TTL expired"); 649 break; 650 case SOCKS5_REQUEST_PROTOCOL_ERROR: 651 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - client protocol error"); 652 break; 653 case SOCKS5_REQUEST_BAD_ADDRESS_TYPE: 654 log_error(LOG_LEVEL_CONNECT, "SOCKS5 request - domain names unsupported"); 655 break; 656 default: 657 log_error(LOG_LEVEL_CONNECT, "SOCKS5 negotiation protocol error"); 658 break; 659 } 660 err = 1; 661 } 662 663 close_socket(sfd); 664 errno = EINVAL; 665 return(JB_INVALID_SOCKET); 666 } 667 457 668 /* 458 669 Local Variables: 459 670 tab-width: 3 -
loadcfg.c
diff -r 6ce92f2e919b loadcfg.c
535 535 #define hash_forward 2029845ul /* "forward" */ 536 536 #define hash_forward_socks4 3963965521ul /* "forward-socks4" */ 537 537 #define hash_forward_socks4a 2639958518ul /* "forward-socks4a" */ 538 #define hash_forward_socks5 3963965522ul /* "forward-socks5" */ 538 539 #define hash_forwarded_connect_retries 101465292ul /* "forwarded-connect-retries" */ 539 540 #define hash_jarfile 2046641ul /* "jarfile" */ 540 541 #define hash_listen_address 1255650842ul /* "listen-address" */ … … 774 775 struct forward_spec *cur_fwd; 775 776 int vec_count; 776 777 char *vec[3]; 778 unsigned long int directive_hash = 0ul; 777 779 778 780 strlcpy(tmp, buf, sizeof(tmp)); 779 781 … … 814 816 savearg(cmd, arg, config); 815 817 816 818 817 switch( hash_string( cmd ) ) 819 directive_hash = hash_string( cmd ); 820 switch( directive_hash ) 818 821 { 819 822 /* ************************************************************************* 820 823 * actionsfile actions-file-name … … 1203 1206 * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port]) 1204 1207 * *************************************************************************/ 1205 1208 case hash_forward_socks4a: 1209 case hash_forward_socks5: 1206 1210 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1); 1207 1211 1208 1212 if (vec_count != 3) … … 1224 1228 continue; 1225 1229 } 1226 1230 1231 if (directive_hash == hash_forward_socks4a) { 1227 1232 cur_fwd->type = SOCKS_4A; 1233 } else { 1234 cur_fwd->type = SOCKS_5; 1235 } 1228 1236 1229 1237 /* Save the URL pattern */ 1230 1238 if (create_url_spec(cur_fwd->url, vec[0])) -
project.h
diff -r 6ce92f2e919b project.h
1474 1474 #define SOCKS_NONE 0 /**< Don't use a SOCKS server */ 1475 1475 #define SOCKS_4 40 /**< original SOCKS 4 protocol */ 1476 1476 #define SOCKS_4A 41 /**< as modified for hosts w/o external DNS */ 1477 #define SOCKS_5 50 /**< as modified for hosts w/o external DNS */ 1477 1478 1478 1479 1479 1480 /** … … 1484 1485 /** URL pattern that this forward_spec is for. */ 1485 1486 struct url_spec url[1]; 1486 1487 1487 /** Connection type. Must be SOCKS_NONE, SOCKS_4, or SOCKS_4A. */1488 /** Connection type. Must be SOCKS_NONE, SOCKS_4, SOCKS_4A or SOCKS_5. */ 1488 1489 int type; 1489 1490 1490 1491 /** SOCKS server hostname. Only valid if "type" is SOCKS_4 or SOCKS_4A. */