• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Socks.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /*
00025   Socks.cc
00026 
00027 
00028 
00029   This file contains the Socks client functionality. Previously this code was
00030   duplicated in UnixNet.cc and NTNetProcessor.cc
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   //we dont have information about the source. set to destination's
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;                   //attempt again
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     // Original was inet_addr, but should hostnames work?
00107     // ats_ip_pton only supports numeric (because other clients
00108     // explicitly want to avoid hostname lookups).
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     // Socks continuation share the user's lock
00141     // so acquiring a lock shouldn't fail
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_;        //assign the original continuation
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       //Debug("Socks", " Got NET_EVENT_OPEN to SOCKS server\n");
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;       //Reserved
00260         if (ats_is_ip4(&server_addr)) {
00261           p[n_bytes++] = 1;       //IPv4 addr
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;       //IPv6 addr
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           //for socks4, ip addr is after the port
00285           memcpy(p + n_bytes,
00286             &server_addr.sin.sin_addr,
00287             4
00288           );
00289           n_bytes += 4;
00290 
00291           p[n_bytes++] = 0;       // NULL
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       /* timeout would be already set when we come here from StartEvent() */
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     //Debug("Socks", "Sent the request to the SOCKS server\n");
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();               // Use the same buffer for a read now
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       //let the client handle the response
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     // Fall Through
00381   case VC_EVENT_READ_COMPLETE:
00382     if (timeout) {
00383       timeout->cancel(this);
00384       timeout = NULL;
00385     }
00386     //Debug("Socks", "Successfully read the reply from the SOCKS server\n");
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         // here either authorization is done or there is another
00397         // stage left.
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       //ink_assert(*(p) == 0);
00411       if (!success) {           // SOCKS request failed
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     /* else
00431        This is server_connect_timeout. So we treat this as server being
00432        down.
00433        Should cancel any pending connect() action. Important on windows
00434 
00435        fall through
00436      */
00437   case VC_EVENT_ERROR:
00438     /*This is mostly ECONNREFUSED on Unix */
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     // BUGBUG:: could be active/inactivity timeout ...
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; //initialize it INKqa08593
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 //  tmp = socks_conf_stuff->ip_range.read_table_from_file(socks_config_fd, "no_socks");
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 };       // initialize all chars to nil
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     // coverity[secure_coding]
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   //for more info on Socks5 see RFC 1928
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;  //version
00615     p[ret++] = (pass_phrase) ? 2 : 1;   //#Methods
00616     p[ret++] = 0;               //no authentication
00617     if (pass_phrase)
00618       p[ret++] = 2;
00619 
00620     break;
00621 
00622   case SOCKS_AUTH_WRITE_COMPLETE:
00623     //return number of bytes to read
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:                  // no authentication required
00633         Debug("Socks", "No authentication required for Socks server");
00634         //make sure this is ok for us. right now it is always ok for us.
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     //This should be inpossible
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   //for more info see RFC 1929
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;                   //version
00692     memcpy(&p[1], pass_phrase, pass_len);
00693 
00694     ret = 1 + pass_len;
00695     break;
00696 
00697   case SOCKS_AUTH_WRITE_COMPLETE:
00698     //return number of bytes to read
00699     ret = 2;
00700     break;
00701 
00702   case SOCKS_AUTH_READ_COMPLETE:
00703 
00704     //if (p[0] == 1) { // skip this. its not clear what this should be.
00705     // NEC thinks it is 5 RFC seems to indicate 1.
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     //else {
00719     //  Debug("Socks", "authPassEvent got wrong version %d from "
00720     //        "Socks server\n", (int)p[0]);
00721     //  ret = -1;
00722     //}
00723 
00724     break;
00725 
00726   default:
00727     ink_assert(!"bad case value");
00728     ret = -1;
00729     break;
00730   }
00731   return ret;
00732 }

Generated by  doxygen 1.7.1