⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socks.cxx

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 CXX
字号:
/* * main.cxx * * PWLib application source file for GetCyberPatrol * * Main program entry point. * * Copyright 98 Equivalence * * $Log: socks.cxx,v $ * Revision 1.4  1999/11/23 08:45:10  robertj * Fixed bug in user/pass authentication version, thanks Dmitry <dipa@linkline.com> * * Revision 1.3  1999/02/16 08:08:06  robertj * MSVC 6.0 compatibility changes. * * Revision 1.2  1998/12/23 00:35:28  robertj * UDP support. * * Revision 1.1  1998/12/22 10:30:24  robertj * Initial revision * */#include <ptlib.h>#include <ptclib/socks.h>#define new PNEW#define SOCKS_VERSION_4 ((BYTE)4)#define SOCKS_VERSION_5 ((BYTE)5)#define SOCKS_CMD_CONNECT       ((BYTE)1)#define SOCKS_CMD_BIND          ((BYTE)2)#define SOCKS_CMD_UDP_ASSOCIATE ((BYTE)3)#define SOCKS_AUTH_NONE      ((BYTE)0)#define SOCKS_AUTH_USER_PASS ((BYTE)2)#define SOCKS_AUTH_FAILED    ((BYTE)0xff)#define SOCKS_ADDR_IPV4       ((BYTE)1)#define SOCKS_ADDR_DOMAINNAME ((BYTE)3)#define SOCKS_ADDR_IPV6       ((BYTE)4)///////////////////////////////////////////////////////////////////////////////PSocksProtocol::PSocksProtocol(WORD port)  : serverHost("proxy"){  serverPort = DefaultServerPort;  remotePort = port;  localPort = 0;  // get proxy information  PConfig config(PConfig::System, "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\");  // get the proxy configuration string  PString str = config.GetString("Internet Settings", "ProxyServer", "");  if (str.Find('=') == P_MAX_INDEX)    SetServer("socks");  else {    PStringArray tokens = str.Tokenise(";");    PINDEX i;    for (i = 0; i < tokens.GetSize(); i++) {      str = tokens[i];      PINDEX equalPos = str.Find('=');      if (equalPos != P_MAX_INDEX && (str.Left(equalPos) *= "socks")) {        SetServer(str.Mid(equalPos+1));        break;      }    }  }}BOOL PSocksProtocol::SetServer(const PString & hostname, const char * service){  return SetServer(hostname, PIPSocket::GetPortByService("tcp", service));}BOOL PSocksProtocol::SetServer(const PString & hostname, WORD port){  PINDEX colon = hostname.Find(':');  if (colon == P_MAX_INDEX)    serverHost = hostname;  else {    unsigned portnum = hostname.Mid(colon+1).AsUnsigned();    if (portnum == 0)      serverHost = hostname;    else {      serverHost = hostname.Left(colon);      port = (WORD)portnum;    }  }  if (port == 0)    port = DefaultServerPort;  serverPort = port;  return TRUE;}void PSocksProtocol::SetAuthentication(const PString & username, const PString & password){  PAssert(authenticationUsername.GetLength() < 256, PInvalidParameter);  authenticationUsername = username;  PAssert(authenticationPassword.GetLength() < 256, PInvalidParameter);  authenticationPassword = password;}BOOL PSocksProtocol::ConnectSocksServer(PTCPSocket & socket){  PIPSocket::Address ipnum;  if (!PIPSocket::GetHostAddress(serverHost, ipnum))    return FALSE;  remotePort = socket.GetPort();  socket.SetPort(serverPort);  return socket.PTCPSocket::Connect(0, ipnum);}BOOL PSocksProtocol::SendSocksCommand(PTCPSocket & socket,                                      BYTE command,                                      const char * hostname,                                      PIPSocket::Address addr){  if (!socket.IsOpen()) {    if (!ConnectSocksServer(socket))      return FALSE;    socket << SOCKS_VERSION_5           << (authenticationUsername.IsEmpty() ? '\001' : '\002') // length           << SOCKS_AUTH_NONE;    if (!authenticationUsername)      socket << SOCKS_AUTH_USER_PASS;  // Simple cleartext username/password    socket.flush();    BYTE auth_pdu[2];    if (!socket.ReadBlock(auth_pdu, sizeof(auth_pdu)))  // Should get 2 byte reply      return FALSE;    if (auth_pdu[0] != SOCKS_VERSION_5 || auth_pdu[1] == SOCKS_AUTH_FAILED) {      socket.Close();      SetErrorCodes(PChannel::AccessDenied, EACCES);      return FALSE;    }    if (auth_pdu[1] == SOCKS_AUTH_USER_PASS) {      // Send username and pasword      socket << '\x01'             << (BYTE)authenticationUsername.GetLength()  // Username length as single byte             << authenticationUsername             << (BYTE)authenticationPassword.GetLength()  // Password length as single byte             << authenticationPassword             << ::flush;      if (!socket.ReadBlock(auth_pdu, sizeof(auth_pdu)))  // Should get 2 byte reply        return FALSE;      if (auth_pdu[0] != SOCKS_VERSION_5 || auth_pdu[1] != 0) {        socket.Close();        SetErrorCodes(PChannel::AccessDenied, EACCES);        return FALSE;      }    }  }  socket << SOCKS_VERSION_5         << command         << '\000'; // Reserved  if (hostname != NULL)    socket << SOCKS_ADDR_DOMAINNAME << (BYTE)strlen(hostname) << hostname;  else    socket << SOCKS_ADDR_IPV4           << addr.Byte1() << addr.Byte2() << addr.Byte3() << addr.Byte4();  socket << (BYTE)(remotePort >> 8) << (BYTE)remotePort         << ::flush;  return ReceiveSocksResponse(socket, localAddress, localPort);}BOOL PSocksProtocol::ReceiveSocksResponse(PTCPSocket & socket,                                          PIPSocket::Address & addr,                                          WORD & port){  int reply;  if ((reply = socket.ReadChar()) < 0)    return FALSE;  if (reply != SOCKS_VERSION_5) {    SetErrorCodes(PChannel::Miscellaneous, EINVAL);    return FALSE;  }  if ((reply = socket.ReadChar()) < 0)    return FALSE;  switch (reply) {    case 0 :  // No error      break;    case 2 :  // Refused permission      SetErrorCodes(PChannel::AccessDenied, EACCES);      return FALSE;    case 3 : // Network unreachable      SetErrorCodes(PChannel::NotFound, ENETUNREACH);      return FALSE;    case 4 : // Host unreachable      SetErrorCodes(PChannel::NotFound, EHOSTUNREACH);      return FALSE;    case 5 : // Connection refused      SetErrorCodes(PChannel::NotFound, EHOSTUNREACH);      return FALSE;    default :      SetErrorCodes(PChannel::Miscellaneous, EINVAL);      return FALSE;  }  // Ignore next byte (reserved)  if ((reply = socket.ReadChar()) < 0)    return FALSE;  // Get type byte for bound address  if ((reply = socket.ReadChar()) < 0)    return FALSE;  switch (reply) {    case SOCKS_ADDR_DOMAINNAME :      // Get length      if ((reply = socket.ReadChar()) < 0)        return FALSE;      if (!PIPSocket::GetHostAddress(socket.ReadString(reply), addr))        return FALSE;      break;    case SOCKS_ADDR_IPV4 :      if (!socket.ReadBlock(&addr, sizeof(addr)))        return FALSE;      break;    default :      SetErrorCodes(PChannel::Miscellaneous, EINVAL);      return FALSE;  }  WORD rxPort;  if (!socket.ReadBlock(&rxPort, sizeof(rxPort)))    return FALSE;  port = PSocket::Net2Host(rxPort);  return TRUE;}///////////////////////////////////////////////////////////////////////////////PSocksSocket::PSocksSocket(WORD port)  : PSocksProtocol(port){}BOOL PSocksSocket::Connect(const PString & address){  if (!SendSocksCommand(*this, SOCKS_CMD_CONNECT, address, 0))    return FALSE;  port = remotePort;  return TRUE;}BOOL PSocksSocket::Connect(const Address & addr){  if (!SendSocksCommand(*this, SOCKS_CMD_CONNECT, NULL, addr))    return FALSE;  port = remotePort;  return TRUE;}BOOL PSocksSocket::Connect(WORD, const Address &){  PAssertAlways(PUnsupportedFeature);  return FALSE;}BOOL PSocksSocket::Listen(unsigned, WORD newPort, Reusability reuse){  PAssert(newPort == 0 && port == 0, PUnsupportedFeature);  PAssert(reuse, PUnsupportedFeature);  if (!SendSocksCommand(*this, SOCKS_CMD_BIND, NULL, 0))    return FALSE;  port = localPort;  return TRUE;}BOOL PSocksSocket::Accept(){  if (!IsOpen())    return FALSE;  return ReceiveSocksResponse(*this, remoteAddress, remotePort);}BOOL PSocksSocket::Accept(PSocket & socket){  // If is right class, transfer the SOCKS socket to class to receive the accept  // The "listener" socket is implicitly closed as there is really only one  // handle in a SOCKS BIND operation.  PAssert(socket.IsDescendant(PSocksSocket::Class()), PUnsupportedFeature);  os_handle = ((PSocksSocket &)socket).TransferHandle(*this);  return Accept();}int PSocksSocket::TransferHandle(PSocksSocket & destination){  // This "transfers" the socket from one onstance to another.  int the_handle = os_handle;  destination.SetReadTimeout(readTimeout);  destination.SetWriteTimeout(writeTimeout);  // Close the instance of the socket but don't actually close handle.  os_handle = -1;  return the_handle;}BOOL PSocksSocket::GetLocalAddress(Address & addr){  if (!IsOpen())    return FALSE;  addr = localAddress;  return TRUE;}BOOL PSocksSocket::GetLocalAddress(Address & addr, WORD & port){  if (!IsOpen())    return FALSE;  addr = localAddress;  port = localPort;  return TRUE;}BOOL PSocksSocket::GetPeerAddress(Address & addr){  if (!IsOpen())    return FALSE;  addr = remoteAddress;  return TRUE;}BOOL PSocksSocket::GetPeerAddress(Address & addr, WORD & port){  if (!IsOpen())    return FALSE;  addr = remoteAddress;  port = remotePort;  return TRUE;}void PSocksSocket::SetErrorCodes(PChannel::Errors errCode, int osErr){  lastError = errCode;  osError = osErr;}///////////////////////////////////////////////////////////////////////////////PSocks4Socket::PSocks4Socket(WORD port)  : PSocksSocket(port){}PSocks4Socket::PSocks4Socket(const PString & host, WORD port)  : PSocksSocket(port){  Connect(host);}PObject * PSocks4Socket::Clone() const{  return new PSocks4Socket(remotePort);}BOOL PSocks4Socket::SendSocksCommand(PTCPSocket & socket,                                     BYTE command,                                     const char * hostname,                                     Address addr){  if (hostname != NULL) {    if (!GetHostAddress(hostname, addr))      return FALSE;  }  if (!IsOpen()) {    if (!ConnectSocksServer(*this))      return FALSE;  }  PString user = PProcess::Current().GetUserName();  socket << SOCKS_VERSION_4         << command         << (BYTE)user.GetLength() << user         << (BYTE)(remotePort >> 8) << (BYTE)remotePort         << addr.Byte1() << addr.Byte2() << addr.Byte3() << addr.Byte4()         << ::flush;  return ReceiveSocksResponse(socket, localAddress, localPort);}BOOL PSocks4Socket::ReceiveSocksResponse(PTCPSocket & socket,                                         Address & addr,                                         WORD & port){  int reply;  if ((reply = socket.ReadChar()) < 0)    return FALSE;  if (reply != SOCKS_VERSION_4) {    SetErrorCodes(PChannel::Miscellaneous, EINVAL);    return FALSE;  }  if ((reply = socket.ReadChar()) < 0)    return FALSE;  switch (reply) {    case 90 :  // No error      break;    case 91 : // Connection refused      SetErrorCodes(PChannel::NotFound, EHOSTUNREACH);      return FALSE;    case 92 :  // Refused permission      SetErrorCodes(PChannel::AccessDenied, EACCES);      return FALSE;    default :      SetErrorCodes(PChannel::Miscellaneous, EINVAL);      return FALSE;  }  WORD rxPort;  if (!socket.ReadBlock(&rxPort, sizeof(rxPort)))    return FALSE;  port = PSocket::Net2Host(rxPort);  return socket.ReadBlock(&addr, sizeof(addr));}///////////////////////////////////////////////////////////////////////////////PSocks5Socket::PSocks5Socket(WORD port)  : PSocksSocket(port){}PSocks5Socket::PSocks5Socket(const PString & host, WORD port)  : PSocksSocket(port){  Connect(host);}PObject * PSocks5Socket::Clone() const{  return new PSocks5Socket(remotePort);}///////////////////////////////////////////////////////////////////////////////PSocksUDPSocket::PSocksUDPSocket(WORD port)  : PSocksProtocol(port){}PSocksUDPSocket::PSocksUDPSocket(const PString & host, WORD port)  : PSocksProtocol(port){  Connect(host);}PObject * PSocksUDPSocket::Clone() const{  return new PSocksUDPSocket(port);}BOOL PSocksUDPSocket::Connect(const PString & address){  if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, address, 0))    return FALSE;  socksControl.GetPeerAddress(serverAddress);  return TRUE;}BOOL PSocksUDPSocket::Connect(const Address & addr){  if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, NULL, addr))    return FALSE;  socksControl.GetPeerAddress(serverAddress);  return TRUE;}BOOL PSocksUDPSocket::Connect(WORD, const Address &){  PAssertAlways(PUnsupportedFeature);  return FALSE;}BOOL PSocksUDPSocket::Listen(unsigned, WORD newPort, Reusability reuse){  PAssert(newPort == 0 && port == 0, PUnsupportedFeature);  PAssert(reuse, PUnsupportedFeature);  if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, NULL, 0))    return FALSE;  socksControl.GetPeerAddress(serverAddress);  port = localPort;  return TRUE;}BOOL PSocksUDPSocket::GetLocalAddress(Address & addr){  if (!IsOpen())    return FALSE;  addr = localAddress;  return TRUE;}BOOL PSocksUDPSocket::GetLocalAddress(Address & addr, WORD & port){  if (!IsOpen())    return FALSE;  addr = localAddress;  port = localPort;  return TRUE;}BOOL PSocksUDPSocket::GetPeerAddress(Address & addr){  if (!IsOpen())    return FALSE;  addr = remoteAddress;  return TRUE;}BOOL PSocksUDPSocket::GetPeerAddress(Address & addr, WORD & port){  if (!IsOpen())    return FALSE;  addr = remoteAddress;  port = remotePort;  return TRUE;}BOOL PSocksUDPSocket::ReadFrom(void * buf, PINDEX len, Address & addr, WORD & port){  PBYTEArray newbuf(len+262);  Address rx_addr;  WORD rx_port;  if (!PUDPSocket::ReadFrom(newbuf.GetPointer(), newbuf.GetSize(), rx_addr, rx_port))    return FALSE;  if (rx_addr != serverAddress || rx_port != serverPort)    return FALSE;  PINDEX port_pos;  switch (newbuf[3]) {    case SOCKS_ADDR_DOMAINNAME :      if (!PIPSocket::GetHostAddress(PString((const char *)&newbuf[5], (PINDEX)newbuf[4]), addr))        return FALSE;      port_pos = newbuf[4]+5;      break;    case SOCKS_ADDR_IPV4 :      memcpy(&addr, &newbuf[4], 4);      port_pos = 4;      break;    default :      SetErrorCodes(PChannel::Miscellaneous, EINVAL);      return FALSE;  }  port = (WORD)((newbuf[port_pos] << 8)|newbuf[port_pos+1]);  memcpy(buf, &newbuf[port_pos+2], len);  return TRUE;}BOOL PSocksUDPSocket::WriteTo(const void * buf, PINDEX len, const Address & addr, WORD port){  PBYTEArray newbuf(len+10);  BYTE * bufptr = newbuf.GetPointer();  // Build header, bytes 0, 1 & 2 are zero  bufptr[3] = SOCKS_ADDR_IPV4;  memcpy(bufptr+4, &addr, 4);  bufptr[8] = (BYTE)(port >> 8);  bufptr[9] = (BYTE)port;  memcpy(bufptr+10, buf, len);  return PUDPSocket::WriteTo(newbuf, newbuf.GetSize(), serverAddress, serverPort);}void PSocksUDPSocket::SetErrorCodes(PChannel::Errors errCode, int osErr){  lastError = errCode;  osError = osErr;}// End of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -