00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "P_Net.h"
00034 #include "I_Layout.h"
00035 #include <ts/IpMapConf.h>
00036
00037 socks_conf_struct *g_socks_conf_stuff = 0;
00038
00039 ClassAllocator<SocksEntry> socksAllocator("socksAllocator");
00040
00041 void
00042 SocksEntry::init(ProxyMutex * m, SocksNetVC * vc, unsigned char socks_support, unsigned char ver)
00043 {
00044 mutex = m;
00045 buf = new_MIOBuffer();
00046 reader = buf->alloc_reader();
00047
00048 socks_cmd = socks_support;
00049
00050 if (ver == SOCKS_DEFAULT_VERSION)
00051 version = netProcessor.socks_conf_stuff->default_version;
00052 else
00053 version = ver;
00054
00055 SET_HANDLER(&SocksEntry::startEvent);
00056
00057 ats_ip_copy(&target_addr, vc->get_local_addr());
00058
00059 #ifdef SOCKS_WITH_TS
00060 req_data.hdr = 0;
00061 req_data.hostname_str = 0;
00062 req_data.api_info = 0;
00063 req_data.xact_start = time(0);
00064
00065 assert(ats_is_ip4(&target_addr));
00066 ats_ip_copy(&req_data.dest_ip, &target_addr);
00067
00068
00069 ats_ip_copy(&req_data.src_ip, &target_addr);
00070
00071 server_params = SocksServerConfig::acquire();
00072 #endif
00073
00074 nattempts = 0;
00075 findServer();
00076
00077 timeout = this_ethread()->schedule_in(this, HRTIME_SECONDS(netProcessor.socks_conf_stuff->server_connect_timeout));
00078 write_done = false;
00079 }
00080
00081 void
00082 SocksEntry::findServer()
00083 {
00084 nattempts++;
00085
00086 #ifdef SOCKS_WITH_TS
00087 if (nattempts == 1) {
00088 ink_assert(server_result.r == PARENT_UNDEFINED);
00089 server_params->findParent(&req_data, &server_result);
00090 } else {
00091
00092 socks_conf_struct *conf = netProcessor.socks_conf_stuff;
00093 if ((nattempts - 1) % conf->per_server_connection_attempts)
00094 return;
00095
00096 server_params->markParentDown(&server_result);
00097
00098 if (nattempts > conf->connection_attempts)
00099 server_result.r = PARENT_FAIL;
00100 else
00101 server_params->nextParent(&req_data, &server_result);
00102 }
00103
00104 switch (server_result.r) {
00105 case PARENT_SPECIFIED:
00106
00107
00108
00109 if (0 == ats_ip_pton(server_result.hostname, &server_addr)) {
00110 ats_ip_port_cast(&server_addr) = htons(server_result.port);
00111 } else {
00112 Debug("SocksParent", "Invalid parent server specified %s", server_result.hostname);
00113 }
00114 break;
00115
00116 default:
00117 ink_assert(!"Unexpected event");
00118 case PARENT_DIRECT:
00119 case PARENT_FAIL:
00120 memset(&server_addr, 0, sizeof(server_addr));
00121 }
00122 #else
00123 if (nattempts > netProcessor.socks_conf_stuff->connection_attempts)
00124 memset(&server_addr, 0, sizeof(server_addr));
00125 else ats_ip_copy(&server_addr, &g_socks_conf_stuff->server_addr);
00126 #endif // SOCKS_WITH_TS
00127
00128 char buff[INET6_ADDRSTRLEN];
00129 Debug("SocksParents", "findServer result: %s:%d",
00130 ats_ip_ntop(&server_addr.sa, buff, sizeof(buff)),
00131 ats_ip_port_host_order(&server_addr)
00132 );
00133 }
00134
00135 void
00136 SocksEntry::free()
00137 {
00138 MUTEX_TRY_LOCK(lock, action_.mutex, this_ethread());
00139 if (!lock) {
00140
00141
00142 ink_assert(0);
00143 return;
00144 }
00145
00146 if (timeout)
00147 timeout->cancel(this);
00148
00149 #ifdef SOCKS_WITH_TS
00150 if (!lerrno && netVConnection && server_result.retry)
00151 server_params->recordRetrySuccess(&server_result);
00152 #endif
00153
00154 if ((action_.cancelled || lerrno) && netVConnection)
00155 netVConnection->do_io_close();
00156
00157 if (!action_.cancelled) {
00158 if (lerrno || !netVConnection) {
00159 Debug("Socks", "retryevent: Sent errno %d to HTTP", lerrno);
00160 NET_INCREMENT_DYN_STAT(socks_connections_unsuccessful_stat);
00161 action_.continuation->handleEvent(NET_EVENT_OPEN_FAILED, (void *)(intptr_t)(-lerrno));
00162 } else {
00163 netVConnection->do_io_read(this, 0, 0);
00164 netVConnection->do_io_write(this, 0, 0);
00165 netVConnection->action_ = action_;
00166 ats_ip_copy(&netVConnection->server_addr, &server_addr);
00167 Debug("Socks", "Sent success to HTTP");
00168 NET_INCREMENT_DYN_STAT(socks_connections_successful_stat);
00169 action_.continuation->handleEvent(NET_EVENT_OPEN, netVConnection);
00170 }
00171 }
00172 #ifdef SOCKS_WITH_TS
00173 SocksServerConfig::release(server_params);
00174 #endif
00175
00176 free_MIOBuffer(buf);
00177 action_ = NULL;
00178 mutex = NULL;
00179 socksAllocator.free(this);
00180 }
00181
00182 int
00183 SocksEntry::startEvent(int event, void *data)
00184 {
00185 if (event == NET_EVENT_OPEN) {
00186 netVConnection = (SocksNetVC *) data;
00187
00188 if (version == SOCKS5_VERSION)
00189 auth_handler = &socks5BasicAuthHandler;
00190
00191 SET_HANDLER((SocksEntryHandler) & SocksEntry::mainEvent);
00192 mainEvent(NET_EVENT_OPEN, data);
00193 } else {
00194 if (timeout) {
00195 timeout->cancel(this);
00196 timeout = NULL;
00197 }
00198
00199 char buff[INET6_ADDRPORTSTRLEN];
00200 Debug("Socks", "Failed to connect to %s", ats_ip_nptop(&server_addr.sa, buff, sizeof(buff)));
00201
00202 findServer();
00203
00204 if (!ats_is_ip(&server_addr)) {
00205 Debug("Socks", "Unable to open connection to the SOCKS server");
00206 lerrno = ESOCK_NO_SOCK_SERVER_CONN;
00207 free();
00208 return EVENT_CONT;
00209 }
00210
00211 if (timeout) {
00212 timeout->cancel(this);
00213 timeout = 0;
00214 }
00215
00216 if (netVConnection) {
00217 netVConnection->do_io_close();
00218 netVConnection = 0;
00219 }
00220
00221 timeout = this_ethread()->schedule_in(this, HRTIME_SECONDS(netProcessor.socks_conf_stuff->server_connect_timeout));
00222
00223 write_done = false;
00224
00225 NetVCOptions options;
00226 options.socks_support = NO_SOCKS;
00227 netProcessor.connect_re(this, &server_addr.sa, &options);
00228 }
00229
00230 return EVENT_CONT;
00231 }
00232
00233 int
00234 SocksEntry::mainEvent(int event, void *data)
00235 {
00236 int ret = EVENT_DONE;
00237 int n_bytes = 0;
00238 unsigned char *p;
00239
00240 switch (event) {
00241
00242 case NET_EVENT_OPEN:
00243 buf->reset();
00244 unsigned short ts;
00245 p = (unsigned char *) buf->start();
00246 ink_assert(netVConnection);
00247
00248 if (auth_handler) {
00249 n_bytes = invokeSocksAuthHandler(auth_handler, SOCKS_AUTH_OPEN, p);
00250 } else {
00251
00252
00253
00254 p[n_bytes++] = version;
00255 p[n_bytes++] = (socks_cmd == NORMAL_SOCKS) ? SOCKS_CONNECT : socks_cmd;
00256 ts = ntohs(ats_ip_port_cast(&server_addr));
00257
00258 if (version == SOCKS5_VERSION) {
00259 p[n_bytes++] = 0;
00260 if (ats_is_ip4(&server_addr)) {
00261 p[n_bytes++] = 1;
00262 memcpy(p + n_bytes,
00263 &server_addr.sin.sin_addr,
00264 4
00265 );
00266 n_bytes += 4;
00267 } else if (ats_is_ip6(&server_addr)) {
00268 p[n_bytes++] = 4;
00269 memcpy(p + n_bytes,
00270 &server_addr.sin6.sin6_addr,
00271 TS_IP6_SIZE
00272 );
00273 n_bytes += TS_IP6_SIZE;
00274 } else {
00275 Debug("Socks", "SOCKS supports only IP addresses.");
00276 }
00277 }
00278
00279 memcpy(p + n_bytes, &ts, 2);
00280 n_bytes += 2;
00281
00282 if (version == SOCKS4_VERSION) {
00283 if (ats_is_ip4(&server_addr)) {
00284
00285 memcpy(p + n_bytes,
00286 &server_addr.sin.sin_addr,
00287 4
00288 );
00289 n_bytes += 4;
00290
00291 p[n_bytes++] = 0;
00292 } else {
00293 Debug("Socks", "SOCKS v4 supports only IPv4 addresses.");
00294 }
00295 }
00296
00297 }
00298
00299 buf->fill(n_bytes);
00300
00301 if (!timeout) {
00302
00303 timeout = this_ethread()->schedule_in(this, HRTIME_SECONDS(netProcessor.socks_conf_stuff->socks_timeout));
00304 }
00305
00306 netVConnection->do_io_write(this, n_bytes, reader, 0);
00307
00308
00309 ret = EVENT_CONT;
00310 break;
00311
00312 case VC_EVENT_WRITE_READY:
00313
00314 ret = EVENT_CONT;
00315 break;
00316
00317 case VC_EVENT_WRITE_COMPLETE:
00318 if (timeout) {
00319 timeout->cancel(this);
00320 timeout = NULL;
00321 write_done = true;
00322 }
00323
00324 buf->reset();
00325
00326 if (auth_handler)
00327 n_bytes = invokeSocksAuthHandler(auth_handler, SOCKS_AUTH_WRITE_COMPLETE, NULL);
00328 else if (socks_cmd == NORMAL_SOCKS)
00329 n_bytes = (version == SOCKS5_VERSION)
00330 ? SOCKS5_REP_LEN : SOCKS4_REP_LEN;
00331 else {
00332 Debug("Socks", "Tunnelling the connection");
00333
00334 free();
00335 break;
00336 }
00337
00338 timeout = this_ethread()->schedule_in(this, HRTIME_SECONDS(netProcessor.socks_conf_stuff->socks_timeout));
00339
00340 netVConnection->do_io_read(this, n_bytes, buf);
00341
00342 ret = EVENT_DONE;
00343 break;
00344
00345 case VC_EVENT_READ_READY:
00346 ret = EVENT_CONT;
00347
00348 if (version == SOCKS5_VERSION && auth_handler == NULL) {
00349 VIO *vio = (VIO *) data;
00350 p = (unsigned char *) buf->start();
00351
00352 if (vio->ndone >= 5) {
00353 int reply_len;
00354
00355 switch (p[3]) {
00356 case SOCKS_ATYPE_IPV4:
00357 reply_len = 10;
00358 break;
00359 case SOCKS_ATYPE_FQHN:
00360 reply_len = 7 + p[4];
00361 break;
00362 case SOCKS_ATYPE_IPV6:
00363 Debug("Socks", "Who is using IPv6 Addr?");
00364 reply_len = 22;
00365 break;
00366 default:
00367 reply_len = INT_MAX;
00368 Debug("Socks", "Illegal address type(%d) in Socks server", (int) p[3]);
00369 }
00370
00371 if (vio->ndone >= reply_len) {
00372 vio->nbytes = vio->ndone;
00373 ret = EVENT_DONE;
00374 }
00375 }
00376 }
00377
00378 if (ret == EVENT_CONT)
00379 break;
00380
00381 case VC_EVENT_READ_COMPLETE:
00382 if (timeout) {
00383 timeout->cancel(this);
00384 timeout = NULL;
00385 }
00386
00387 p = (unsigned char *) buf->start();
00388
00389 if (auth_handler) {
00390 SocksAuthHandler temp = auth_handler;
00391
00392 if (invokeSocksAuthHandler(auth_handler, SOCKS_AUTH_READ_COMPLETE, p) < 0) {
00393 lerrno = ESOCK_DENIED;
00394 free();
00395 } else if (auth_handler != temp) {
00396
00397
00398 mainEvent(NET_EVENT_OPEN, NULL);
00399 }
00400
00401 } else {
00402
00403 bool success;
00404 if (version == SOCKS5_VERSION) {
00405 success = (p[0] == SOCKS5_VERSION && p[1] == SOCKS5_REQ_GRANTED);
00406 Debug("Socks", "received reply of length %" PRId64" addr type %d", ((VIO *) data)->ndone, (int) p[3]);
00407 } else
00408 success = (p[0] == 0 && p[1] == SOCKS4_REQ_GRANTED);
00409
00410
00411 if (!success) {
00412 Debug("Socks", "Socks request denied %d", (int) *(p + 1));
00413 lerrno = ESOCK_DENIED;
00414 } else {
00415 Debug("Socks", "Socks request successful %d", (int) *(p + 1));
00416 lerrno = 0;
00417 }
00418 free();
00419 }
00420
00421 break;
00422
00423 case EVENT_INTERVAL:
00424 timeout = NULL;
00425 if (write_done) {
00426 lerrno = ESOCK_TIMEOUT;
00427 free();
00428 break;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437 case VC_EVENT_ERROR:
00438
00439 SET_HANDLER(&SocksEntry::startEvent);
00440 startEvent(NET_EVENT_OPEN_FAILED, NULL);
00441 break;
00442
00443 case VC_EVENT_EOS:
00444 case VC_EVENT_INACTIVITY_TIMEOUT:
00445 case VC_EVENT_ACTIVE_TIMEOUT:
00446 Debug("Socks", "VC_EVENT error: %s", get_vc_event_name(event));
00447 lerrno = ESOCK_NO_SOCK_SERVER_CONN;
00448 free();
00449 break;
00450 default:
00451
00452 ink_assert(!"bad case value");
00453 Debug("Socks", "Bad Case/Net Error Event");
00454 lerrno = ESOCK_NO_SOCK_SERVER_CONN;
00455 free();
00456 break;
00457 }
00458
00459 return ret;
00460 }
00461
00462 void
00463 loadSocksConfiguration(socks_conf_struct * socks_conf_stuff)
00464 {
00465 int socks_config_fd = -1;
00466 char config_pathname[PATH_NAME_MAX + 1];
00467 char *socks_config_file = NULL;
00468 #ifdef SOCKS_WITH_TS
00469 char *tmp;
00470 #endif
00471
00472 socks_conf_stuff->accept_enabled = 0;
00473 socks_conf_stuff->socks_needed = REC_ConfigReadInteger("proxy.config.socks.socks_needed");
00474 if (!socks_conf_stuff->socks_needed) {
00475 Debug("Socks", "Socks Turned Off");
00476 return;
00477 }
00478
00479 socks_conf_stuff->default_version = REC_ConfigReadInteger("proxy.config.socks.socks_version");
00480 Debug("Socks", "Socks Version %d", socks_conf_stuff->default_version);
00481
00482 if (socks_conf_stuff->default_version != 4 && socks_conf_stuff->default_version != 5) {
00483 Error("SOCKS Config: Unsupported Version: %d. SOCKS Turned off", socks_conf_stuff->default_version);
00484 goto error;
00485 }
00486
00487 socks_conf_stuff->server_connect_timeout = REC_ConfigReadInteger("proxy.config.socks.server_connect_timeout");
00488 socks_conf_stuff->socks_timeout = REC_ConfigReadInteger("proxy.config.socks.socks_timeout");
00489 Debug("Socks", "server connect timeout: %d socks respnonse timeout %d",
00490 socks_conf_stuff->server_connect_timeout, socks_conf_stuff->socks_timeout);
00491
00492 socks_conf_stuff->per_server_connection_attempts =
00493 REC_ConfigReadInteger("proxy.config.socks.per_server_connection_attempts");
00494 socks_conf_stuff->connection_attempts = REC_ConfigReadInteger("proxy.config.socks.connection_attempts");
00495
00496 socks_conf_stuff->accept_enabled = REC_ConfigReadInteger("proxy.config.socks.accept_enabled");
00497 socks_conf_stuff->accept_port = REC_ConfigReadInteger("proxy.config.socks.accept_port");
00498 socks_conf_stuff->http_port = REC_ConfigReadInteger("proxy.config.socks.http_port");
00499 Debug("SocksProxy", "Read SocksProxy info: accept_enabled = %d "
00500 "accept_port = %d http_port = %d", socks_conf_stuff->accept_enabled,
00501 socks_conf_stuff->accept_port, socks_conf_stuff->http_port);
00502
00503 #ifdef SOCKS_WITH_TS
00504 SocksServerConfig::startup();
00505 #endif
00506
00507 socks_config_file = REC_ConfigReadString("proxy.config.socks.socks_config_file");
00508
00509 if (!socks_config_file) {
00510 Error("SOCKS Config: could not read config file name. SOCKS Turned off");
00511 goto error;
00512 }
00513
00514 Layout::relative_to(config_pathname, sizeof(config_pathname),
00515 Layout::get()->sysconfdir, socks_config_file);
00516 ats_free(socks_config_file);
00517 Debug("Socks", "Socks Config File: %s", config_pathname);
00518
00519 socks_config_fd =::open(config_pathname, O_RDONLY);
00520
00521 if (socks_config_fd < 0) {
00522 Error("SOCKS Config: could not open config file '%s'. SOCKS Turned off", config_pathname);
00523 goto error;
00524 }
00525 #ifdef SOCKS_WITH_TS
00526 tmp = Load_IpMap_From_File(
00527 &socks_conf_stuff->ip_map,
00528 socks_config_fd,
00529 "no_socks"
00530 );
00531
00532
00533 if (tmp) {
00534 Error("SOCKS Config: Error while reading ip_range: %s.", tmp);
00535 ats_free(tmp);
00536 goto error;
00537 }
00538 #endif
00539
00540 if (loadSocksAuthInfo(socks_config_fd, socks_conf_stuff) != 0) {
00541 Error("SOCKS Config: Error while reading Socks auth info");
00542 goto error;
00543 }
00544 Debug("Socks", "Socks Turned on");
00545 ::close(socks_config_fd);
00546
00547 return;
00548 error:
00549
00550 socks_conf_stuff->socks_needed = 0;
00551 socks_conf_stuff->accept_enabled = 0;
00552 if (socks_config_fd >= 0)
00553 ::close(socks_config_fd);
00554
00555 }
00556
00557 int
00558 loadSocksAuthInfo(int fd, socks_conf_struct * socks_stuff)
00559 {
00560 char c = '\0';
00561 char line[256] = { 0 };
00562 char user_name[256] = { 0 };
00563 char passwd[256] = { 0 };
00564
00565 if (lseek(fd, 0, SEEK_SET) < 0) {
00566 Warning("Can not seek on Socks configuration file\n");
00567 return -1;
00568 }
00569
00570 bool end_of_file = false;
00571 do {
00572 int n = 0, rc;
00573 while (((rc = read(fd, &c, 1)) == 1) && (c != '\n') && (n < 254))
00574 line[n++] = c;
00575 if (rc <= 0)
00576 end_of_file = true;
00577 line[n] = '\0';
00578
00579
00580 rc = sscanf(line, " auth u %255s %255s ", user_name, passwd);
00581 if (rc >= 2) {
00582 int len1 = strlen(user_name);
00583 int len2 = strlen(passwd);
00584
00585 Debug("Socks", "Read user_name(%s) and passwd(%s) from config file", user_name, passwd);
00586
00587 socks_stuff->user_name_n_passwd_len = len1 + len2 + 2;
00588
00589 char *ptr = (char *)ats_malloc(socks_stuff->user_name_n_passwd_len);
00590 ptr[0] = len1;
00591 memcpy(&ptr[1], user_name, len1);
00592 ptr[len1 + 1] = len2;
00593 memcpy(&ptr[len1 + 2], passwd, len2);
00594
00595 socks_stuff->user_name_n_passwd = ptr;
00596
00597 return 0;
00598 }
00599 } while (!end_of_file);
00600
00601 return 0;
00602 }
00603
00604 int
00605 socks5BasicAuthHandler(int event, unsigned char *p, void (**h_ptr) (void))
00606 {
00607
00608 int ret = 0;
00609 char *pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd;
00610
00611 switch (event) {
00612
00613 case SOCKS_AUTH_OPEN:
00614 p[ret++] = SOCKS5_VERSION;
00615 p[ret++] = (pass_phrase) ? 2 : 1;
00616 p[ret++] = 0;
00617 if (pass_phrase)
00618 p[ret++] = 2;
00619
00620 break;
00621
00622 case SOCKS_AUTH_WRITE_COMPLETE:
00623
00624 ret = 2;
00625 break;
00626
00627 case SOCKS_AUTH_READ_COMPLETE:
00628
00629 if (p[0] == SOCKS5_VERSION) {
00630 switch (p[1]) {
00631
00632 case 0:
00633 Debug("Socks", "No authentication required for Socks server");
00634
00635 *h_ptr = NULL;
00636 break;
00637
00638 case 2:
00639 Debug("Socks", "Socks server wants username/passwd");
00640 if (!pass_phrase) {
00641 Debug("Socks", "Buggy Socks server: asks for username/passwd " "when not supplied as an option");
00642 ret = -1;
00643 *h_ptr = NULL;
00644 } else
00645 *(SocksAuthHandler *) h_ptr = &socks5PasswdAuthHandler;
00646
00647 break;
00648
00649 case 0xff:
00650 Debug("Socks", "None of the Socks authentcations is acceptable " "to the server");
00651 *h_ptr = NULL;
00652 ret = -1;
00653 break;
00654
00655 default:
00656 Debug("Socks", "Unexpected Socks auth method (%d) from the server", (int) p[1]);
00657 ret = -1;
00658 break;
00659 }
00660 } else {
00661 Debug("Socks", "authEvent got wrong version %d from the Socks server", (int) p[0]);
00662 ret = -1;
00663 }
00664
00665 break;
00666
00667 default:
00668
00669 ink_assert(!"bad case value");
00670 ret = -1;
00671 break;
00672 }
00673 return ret;
00674 }
00675
00676 int
00677 socks5PasswdAuthHandler(int event, unsigned char *p, void (**h_ptr) (void))
00678 {
00679
00680 int ret = 0;
00681 char *pass_phrase;
00682 int pass_len;
00683
00684 switch (event) {
00685
00686 case SOCKS_AUTH_OPEN:
00687 pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd;
00688 pass_len = netProcessor.socks_conf_stuff->user_name_n_passwd_len;
00689 ink_assert(pass_phrase);
00690
00691 p[0] = 1;
00692 memcpy(&p[1], pass_phrase, pass_len);
00693
00694 ret = 1 + pass_len;
00695 break;
00696
00697 case SOCKS_AUTH_WRITE_COMPLETE:
00698
00699 ret = 2;
00700 break;
00701
00702 case SOCKS_AUTH_READ_COMPLETE:
00703
00704
00705
00706 switch (p[1]) {
00707
00708 case 0:
00709 Debug("Socks", "Username/Passwd succeded");
00710 *h_ptr = NULL;
00711 break;
00712
00713 default:
00714 Debug("Socks", "Username/Passwd authentication failed ret_code: %d", (int) p[1]);
00715 ret = -1;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724 break;
00725
00726 default:
00727 ink_assert(!"bad case value");
00728 ret = -1;
00729 break;
00730 }
00731 return ret;
00732 }