00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #if !defined(CURL_DISABLE_PROXY)
00026
00027 #ifdef HAVE_NETINET_IN_H
00028 #include <netinet/in.h>
00029 #endif
00030 #ifdef HAVE_ARPA_INET_H
00031 #include <arpa/inet.h>
00032 #endif
00033
00034 #include "urldata.h"
00035 #include "sendf.h"
00036 #include "select.h"
00037 #include "connect.h"
00038 #include "timeval.h"
00039 #include "socks.h"
00040
00041
00042 #include "memdebug.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051 int Curl_blockread_all(struct connectdata *conn,
00052 curl_socket_t sockfd,
00053 char *buf,
00054 ssize_t buffersize,
00055 ssize_t *n)
00056 {
00057 ssize_t nread;
00058 ssize_t allread = 0;
00059 int result;
00060 time_t timeleft;
00061 *n = 0;
00062 for(;;) {
00063 timeleft = Curl_timeleft(conn->data, NULL, TRUE);
00064 if(timeleft < 0) {
00065
00066 result = CURLE_OPERATION_TIMEDOUT;
00067 break;
00068 }
00069 if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
00070 result = ~CURLE_OK;
00071 break;
00072 }
00073 result = Curl_read_plain(sockfd, buf, buffersize, &nread);
00074 if(CURLE_AGAIN == result)
00075 continue;
00076 else if(result)
00077 break;
00078
00079 if(buffersize == nread) {
00080 allread += nread;
00081 *n = allread;
00082 result = CURLE_OK;
00083 break;
00084 }
00085 if(!nread) {
00086 result = ~CURLE_OK;
00087 break;
00088 }
00089
00090 buffersize -= nread;
00091 buf += nread;
00092 allread += nread;
00093 }
00094 return result;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 CURLcode Curl_SOCKS4(const char *proxy_name,
00109 const char *hostname,
00110 int remote_port,
00111 int sockindex,
00112 struct connectdata *conn)
00113 {
00114 const bool protocol4a =
00115 (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
00116 #define SOCKS4REQLEN 262
00117 unsigned char socksreq[SOCKS4REQLEN];
00118
00119 int result;
00120 CURLcode code;
00121 curl_socket_t sock = conn->sock[sockindex];
00122 struct Curl_easy *data = conn->data;
00123
00124 if(Curl_timeleft(data, NULL, TRUE) < 0) {
00125
00126 failf(data, "Connection time-out");
00127 return CURLE_OPERATION_TIMEDOUT;
00128 }
00129
00130 if(conn->bits.httpproxy)
00131 infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
00132 protocol4a ? "a" : "", hostname, remote_port);
00133
00134 (void)curlx_nonblock(sock, FALSE);
00135
00136 infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 socksreq[0] = 4;
00150 socksreq[1] = 1;
00151 socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff);
00152 socksreq[3] = (unsigned char)(remote_port & 0xff);
00153
00154
00155 if(!protocol4a) {
00156 struct Curl_dns_entry *dns;
00157 Curl_addrinfo *hp=NULL;
00158 int rc;
00159
00160 rc = Curl_resolv(conn, hostname, remote_port, &dns);
00161
00162 if(rc == CURLRESOLV_ERROR)
00163 return CURLE_COULDNT_RESOLVE_PROXY;
00164
00165 if(rc == CURLRESOLV_PENDING)
00166
00167 (void)Curl_resolver_wait_resolv(conn, &dns);
00168
00169
00170
00171
00172
00173 if(dns)
00174 hp=dns->addr;
00175 if(hp) {
00176 char buf[64];
00177 Curl_printable_address(hp, buf, sizeof(buf));
00178
00179 if(hp->ai_family == AF_INET) {
00180 struct sockaddr_in *saddr_in;
00181
00182 saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
00183 socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0];
00184 socksreq[5] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[1];
00185 socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2];
00186 socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3];
00187
00188 infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
00189 }
00190 else {
00191 hp = NULL;
00192
00193 failf(data, "SOCKS4 connection to %s not supported\n", buf);
00194 }
00195
00196 Curl_resolv_unlock(data, dns);
00197 }
00198 if(!hp) {
00199 failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
00200 hostname);
00201 return CURLE_COULDNT_RESOLVE_HOST;
00202 }
00203 }
00204
00205
00206
00207
00208 socksreq[8] = 0;
00209 if(proxy_name) {
00210 size_t plen = strlen(proxy_name);
00211 if(plen >= sizeof(socksreq) - 8) {
00212 failf(data, "Too long SOCKS proxy name, can't use!\n");
00213 return CURLE_COULDNT_CONNECT;
00214 }
00215
00216 memcpy(socksreq + 8, proxy_name, plen+1);
00217 }
00218
00219
00220
00221
00222 {
00223 ssize_t actualread;
00224 ssize_t written;
00225 ssize_t hostnamelen = 0;
00226 int packetsize = 9 +
00227 (int)strlen((char *)socksreq + 8);
00228
00229
00230 if(protocol4a) {
00231 socksreq[4] = 0;
00232 socksreq[5] = 0;
00233 socksreq[6] = 0;
00234 socksreq[7] = 1;
00235
00236 hostnamelen = (ssize_t)strlen(hostname) + 1;
00237 if(packetsize + hostnamelen <= SOCKS4REQLEN)
00238 strcpy((char *)socksreq + packetsize, hostname);
00239 else
00240 hostnamelen = 0;
00241 }
00242
00243
00244 code = Curl_write_plain(conn, sock, (char *)socksreq,
00245 packetsize + hostnamelen,
00246 &written);
00247 if(code || (written != packetsize + hostnamelen)) {
00248 failf(data, "Failed to send SOCKS4 connect request.");
00249 return CURLE_COULDNT_CONNECT;
00250 }
00251 if(protocol4a && hostnamelen == 0) {
00252
00253 hostnamelen = (ssize_t)strlen(hostname) + 1;
00254 code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
00255 &written);
00256 if(code || (written != hostnamelen)) {
00257 failf(data, "Failed to send SOCKS4 connect request.");
00258 return CURLE_COULDNT_CONNECT;
00259 }
00260 }
00261
00262 packetsize = 8;
00263
00264
00265 result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
00266 &actualread);
00267 if(result || (actualread != packetsize)) {
00268 failf(data, "Failed to receive SOCKS4 connect request ack.");
00269 return CURLE_COULDNT_CONNECT;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 if(socksreq[0] != 0) {
00293 failf(data,
00294 "SOCKS4 reply has wrong version, version should be 4.");
00295 return CURLE_COULDNT_CONNECT;
00296 }
00297
00298
00299 switch(socksreq[1]) {
00300 case 90:
00301 infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
00302 break;
00303 case 91:
00304 failf(data,
00305 "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
00306 ", request rejected or failed.",
00307 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00308 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00309 (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
00310 (unsigned char)socksreq[1]);
00311 return CURLE_COULDNT_CONNECT;
00312 case 92:
00313 failf(data,
00314 "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
00315 ", request rejected because SOCKS server cannot connect to "
00316 "identd on the client.",
00317 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00318 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00319 (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
00320 (unsigned char)socksreq[1]);
00321 return CURLE_COULDNT_CONNECT;
00322 case 93:
00323 failf(data,
00324 "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
00325 ", request rejected because the client program and identd "
00326 "report different user-ids.",
00327 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00328 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00329 (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
00330 (unsigned char)socksreq[1]);
00331 return CURLE_COULDNT_CONNECT;
00332 default:
00333 failf(data,
00334 "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
00335 ", Unknown.",
00336 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00337 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00338 (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
00339 (unsigned char)socksreq[1]);
00340 return CURLE_COULDNT_CONNECT;
00341 }
00342 }
00343
00344 (void)curlx_nonblock(sock, TRUE);
00345
00346 return CURLE_OK;
00347 }
00348
00349
00350
00351
00352
00353 CURLcode Curl_SOCKS5(const char *proxy_name,
00354 const char *proxy_password,
00355 const char *hostname,
00356 int remote_port,
00357 int sockindex,
00358 struct connectdata *conn)
00359 {
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 unsigned char socksreq[600];
00378 ssize_t actualread;
00379 ssize_t written;
00380 int result;
00381 CURLcode code;
00382 curl_socket_t sock = conn->sock[sockindex];
00383 struct Curl_easy *data = conn->data;
00384 time_t timeout;
00385 bool socks5_resolve_local =
00386 (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
00387 const size_t hostname_len = strlen(hostname);
00388 ssize_t len = 0;
00389
00390 if(conn->bits.httpproxy)
00391 infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
00392 hostname, remote_port);
00393
00394
00395 if(!socks5_resolve_local && hostname_len > 255) {
00396 infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
00397 "length > 255 [actual len=%zu]\n", hostname_len);
00398 socks5_resolve_local = TRUE;
00399 }
00400
00401
00402 timeout = Curl_timeleft(data, NULL, TRUE);
00403
00404 if(timeout < 0) {
00405
00406 failf(data, "Connection time-out");
00407 return CURLE_OPERATION_TIMEDOUT;
00408 }
00409
00410 (void)curlx_nonblock(sock, TRUE);
00411
00412
00413 result = SOCKET_WRITABLE(sock, timeout);
00414
00415 if(-1 == result) {
00416 failf(conn->data, "SOCKS5: no connection here");
00417 return CURLE_COULDNT_CONNECT;
00418 }
00419 else if(0 == result) {
00420 failf(conn->data, "SOCKS5: connection timeout");
00421 return CURLE_OPERATION_TIMEDOUT;
00422 }
00423
00424 if(result & CURL_CSELECT_ERR) {
00425 failf(conn->data, "SOCKS5: error occurred during connection");
00426 return CURLE_COULDNT_CONNECT;
00427 }
00428
00429 socksreq[0] = 5;
00430 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00431 socksreq[1] = (char)(proxy_name ? 3 : 2);
00432 socksreq[2] = 0;
00433 socksreq[3] = 1;
00434 socksreq[4] = 2;
00435 #else
00436 socksreq[1] = (char)(proxy_name ? 2 : 1);
00437 socksreq[2] = 0;
00438 socksreq[3] = 2;
00439 #endif
00440
00441 (void)curlx_nonblock(sock, FALSE);
00442
00443 infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
00444
00445 code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
00446 &written);
00447 if(code || (written != (2 + (int)socksreq[1]))) {
00448 failf(data, "Unable to send initial SOCKS5 request.");
00449 return CURLE_COULDNT_CONNECT;
00450 }
00451
00452 (void)curlx_nonblock(sock, TRUE);
00453
00454 result = SOCKET_READABLE(sock, timeout);
00455
00456 if(-1 == result) {
00457 failf(conn->data, "SOCKS5 nothing to read");
00458 return CURLE_COULDNT_CONNECT;
00459 }
00460 else if(0 == result) {
00461 failf(conn->data, "SOCKS5 read timeout");
00462 return CURLE_OPERATION_TIMEDOUT;
00463 }
00464
00465 if(result & CURL_CSELECT_ERR) {
00466 failf(conn->data, "SOCKS5 read error occurred");
00467 return CURLE_RECV_ERROR;
00468 }
00469
00470 (void)curlx_nonblock(sock, FALSE);
00471
00472 result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
00473 if(result || (actualread != 2)) {
00474 failf(data, "Unable to receive initial SOCKS5 response.");
00475 return CURLE_COULDNT_CONNECT;
00476 }
00477
00478 if(socksreq[0] != 5) {
00479 failf(data, "Received invalid version in initial SOCKS5 response.");
00480 return CURLE_COULDNT_CONNECT;
00481 }
00482 if(socksreq[1] == 0) {
00483
00484 ;
00485 }
00486 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00487 else if(socksreq[1] == 1) {
00488 code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
00489 if(code) {
00490 failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
00491 return CURLE_COULDNT_CONNECT;
00492 }
00493 }
00494 #endif
00495 else if(socksreq[1] == 2) {
00496
00497 size_t proxy_name_len, proxy_password_len;
00498 if(proxy_name && proxy_password) {
00499 proxy_name_len = strlen(proxy_name);
00500 proxy_password_len = strlen(proxy_password);
00501 }
00502 else {
00503 proxy_name_len = 0;
00504 proxy_password_len = 0;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 len = 0;
00515 socksreq[len++] = 1;
00516 socksreq[len++] = (unsigned char) proxy_name_len;
00517 if(proxy_name && proxy_name_len)
00518 memcpy(socksreq + len, proxy_name, proxy_name_len);
00519 len += proxy_name_len;
00520 socksreq[len++] = (unsigned char) proxy_password_len;
00521 if(proxy_password && proxy_password_len)
00522 memcpy(socksreq + len, proxy_password, proxy_password_len);
00523 len += proxy_password_len;
00524
00525 code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
00526 if(code || (len != written)) {
00527 failf(data, "Failed to send SOCKS5 sub-negotiation request.");
00528 return CURLE_COULDNT_CONNECT;
00529 }
00530
00531 result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
00532 if(result || (actualread != 2)) {
00533 failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
00534 return CURLE_COULDNT_CONNECT;
00535 }
00536
00537
00538 if(socksreq[1] != 0) {
00539 failf(data, "User was rejected by the SOCKS5 server (%d %d).",
00540 socksreq[0], socksreq[1]);
00541 return CURLE_COULDNT_CONNECT;
00542 }
00543
00544
00545 }
00546 else {
00547
00548 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00549 if(socksreq[1] == 255) {
00550 #else
00551 if(socksreq[1] == 1) {
00552 failf(data,
00553 "SOCKS5 GSSAPI per-message authentication is not supported.");
00554 return CURLE_COULDNT_CONNECT;
00555 }
00556 else if(socksreq[1] == 255) {
00557 #endif
00558 if(!proxy_name || !*proxy_name) {
00559 failf(data,
00560 "No authentication method was acceptable. (It is quite likely"
00561 " that the SOCKS5 server wanted a username/password, since none"
00562 " was supplied to the server on this connection.)");
00563 }
00564 else {
00565 failf(data, "No authentication method was acceptable.");
00566 }
00567 return CURLE_COULDNT_CONNECT;
00568 }
00569 else {
00570 failf(data,
00571 "Undocumented SOCKS5 mode attempted to be used by server.");
00572 return CURLE_COULDNT_CONNECT;
00573 }
00574 }
00575
00576
00577 len = 0;
00578 socksreq[len++] = 5;
00579 socksreq[len++] = 1;
00580 socksreq[len++] = 0;
00581
00582 if(!socks5_resolve_local) {
00583 socksreq[len++] = 3;
00584 socksreq[len++] = (char) hostname_len;
00585 memcpy(&socksreq[len], hostname, hostname_len);
00586 len += hostname_len;
00587 }
00588 else {
00589 struct Curl_dns_entry *dns;
00590 Curl_addrinfo *hp = NULL;
00591 int rc = Curl_resolv(conn, hostname, remote_port, &dns);
00592
00593 if(rc == CURLRESOLV_ERROR)
00594 return CURLE_COULDNT_RESOLVE_HOST;
00595
00596 if(rc == CURLRESOLV_PENDING) {
00597
00598 code = Curl_resolver_wait_resolv(conn, &dns);
00599 if(code)
00600 return code;
00601 }
00602
00603
00604
00605
00606
00607 if(dns)
00608 hp=dns->addr;
00609 if(hp) {
00610 int i;
00611 char buf[64];
00612 Curl_printable_address(hp, buf, sizeof(buf));
00613
00614 if(hp->ai_family == AF_INET) {
00615 struct sockaddr_in *saddr_in;
00616 socksreq[len++] = 1;
00617
00618 saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
00619 for(i = 0; i < 4; i++) {
00620 socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
00621 }
00622
00623 infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
00624 }
00625 #ifdef ENABLE_IPV6
00626 else if(hp->ai_family == AF_INET6) {
00627 struct sockaddr_in6 *saddr_in6;
00628 socksreq[len++] = 4;
00629
00630 saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
00631 for(i = 0; i < 16; i++) {
00632 socksreq[len++] =
00633 ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
00634 }
00635
00636 infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
00637 }
00638 #endif
00639 else {
00640 hp = NULL;
00641
00642 failf(data, "SOCKS5 connection to %s not supported\n", buf);
00643 }
00644
00645 Curl_resolv_unlock(data, dns);
00646 }
00647 if(!hp) {
00648 failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
00649 hostname);
00650 return CURLE_COULDNT_RESOLVE_HOST;
00651 }
00652 }
00653
00654 socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff);
00655 socksreq[len++] = (unsigned char)(remote_port & 0xff);
00656
00657 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00658 if(conn->socks5_gssapi_enctype) {
00659 failf(data, "SOCKS5 GSS-API protection not yet implemented.");
00660 }
00661 else
00662 #endif
00663 code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
00664
00665 if(code || (len != written)) {
00666 failf(data, "Failed to send SOCKS5 connect request.");
00667 return CURLE_COULDNT_CONNECT;
00668 }
00669
00670 len = 10;
00671
00672 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00673 if(conn->socks5_gssapi_enctype) {
00674 failf(data, "SOCKS5 GSS-API protection not yet implemented.");
00675 }
00676 else
00677 #endif
00678 result = Curl_blockread_all(conn, sock, (char *)socksreq,
00679 len, &actualread);
00680
00681 if(result || (len != actualread)) {
00682 failf(data, "Failed to receive SOCKS5 connect request ack.");
00683 return CURLE_COULDNT_CONNECT;
00684 }
00685
00686 if(socksreq[0] != 5) {
00687 failf(data,
00688 "SOCKS5 reply has wrong version, version should be 5.");
00689 return CURLE_COULDNT_CONNECT;
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 if(socksreq[3] == 3) {
00710
00711 int addrlen = (int) socksreq[4];
00712 len = 5 + addrlen + 2;
00713 }
00714 else if(socksreq[3] == 4) {
00715
00716 len = 4 + 16 + 2;
00717 }
00718
00719
00720 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00721 if(!conn->socks5_gssapi_enctype) {
00722
00723 #endif
00724 if(len > 10) {
00725 result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
00726 len - 10, &actualread);
00727 if(result || ((len - 10) != actualread)) {
00728 failf(data, "Failed to receive SOCKS5 connect request ack.");
00729 return CURLE_COULDNT_CONNECT;
00730 }
00731 }
00732 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
00733 }
00734 #endif
00735
00736 if(socksreq[1] != 0) {
00737 if(socksreq[3] == 1) {
00738 failf(data,
00739 "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
00740 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00741 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00742 (((unsigned char)socksreq[8] << 8) |
00743 (unsigned char)socksreq[9]),
00744 (unsigned char)socksreq[1]);
00745 }
00746 else if(socksreq[3] == 3) {
00747 unsigned char port_upper = (unsigned char)socksreq[len - 2];
00748 socksreq[len - 2] = 0;
00749 failf(data,
00750 "Can't complete SOCKS5 connection to %s:%d. (%d)",
00751 (char *)&socksreq[5],
00752 ((port_upper << 8) |
00753 (unsigned char)socksreq[len - 1]),
00754 (unsigned char)socksreq[1]);
00755 socksreq[len - 2] = port_upper;
00756 }
00757 else if(socksreq[3] == 4) {
00758 failf(data,
00759 "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
00760 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
00761 (unsigned char)socksreq[4], (unsigned char)socksreq[5],
00762 (unsigned char)socksreq[6], (unsigned char)socksreq[7],
00763 (unsigned char)socksreq[8], (unsigned char)socksreq[9],
00764 (unsigned char)socksreq[10], (unsigned char)socksreq[11],
00765 (unsigned char)socksreq[12], (unsigned char)socksreq[13],
00766 (unsigned char)socksreq[14], (unsigned char)socksreq[15],
00767 (unsigned char)socksreq[16], (unsigned char)socksreq[17],
00768 (unsigned char)socksreq[18], (unsigned char)socksreq[19],
00769 (((unsigned char)socksreq[20] << 8) |
00770 (unsigned char)socksreq[21]),
00771 (unsigned char)socksreq[1]);
00772 }
00773 return CURLE_COULDNT_CONNECT;
00774 }
00775 else {
00776 infof(data, "SOCKS5 request granted.\n");
00777 }
00778
00779 (void)curlx_nonblock(sock, TRUE);
00780 return CURLE_OK;
00781 }
00782
00783 #endif
00784