Ticket #8048: 8084.patch
File 8084.patch, 7.3 KB (added by , 12 years ago) |
---|
-
src/engine/proxy.cpp
# HG changeset patch # User esminis@esminis # Date 1359501956 -7200 # Node ID a312537b578938b90d44709b37ecb0809a653950 # Parent c915a6d4a543533db19fd62d3fddb51d3b6226dc #8048 Support SOCKS 4 diff -r c915a6d4a543 -r a312537b5789 src/engine/proxy.cpp
a b 2 2 #include "proxy.h" 3 3 #include <errno.h> 4 4 #include "ControlSocket.h" 5 #include <wx/sckaddr.h> 5 6 6 7 enum handshake_state 7 8 { … … 11 12 socks5_auth, 12 13 socks5_request, 13 14 socks5_request_addrtype, 14 socks5_request_address 15 socks5_request_address, 16 17 socks4_handshake 15 18 }; 16 19 17 20 CProxySocket::CProxySocket(CSocketEventHandler* pEvtHandler, CSocket* pSocket, CControlSocket* pOwner) … … 81 84 82 85 const wxWX2MBbuf host_raw = host.mb_str(wxConvUTF8); 83 86 84 if (type != HTTP && type != SOCKS5 )87 if (type != HTTP && type != SOCKS5 && type != SOCKS4) 85 88 return EPROTONOSUPPORT; 86 89 87 90 m_user = user; … … 134 137 m_recvBufferLen = 4096; 135 138 m_recvBufferPos = 0; 136 139 } 140 else if (type == SOCKS4) 141 { 142 wxString ip = m_host; 143 if (!IsIpAddress(m_host)) { 144 wxIPV4address address; 145 address.Hostname(host); 146 ip = address.IPAddress(); 147 } else if (!GetIPV6LongForm(m_host).empty()) { 148 m_pOwner->LogMessage(Error, _("IPv6 addresses are not supported with SOCKS4 proxy")); 149 return EINVAL; 150 } 151 m_pOwner->LogMessage(Status, _("SOCKS4 proxy will connect to: %s"), ip.c_str()); 152 153 m_pSendBuffer = new char[9]; 154 m_pSendBuffer[0] = 4; // Protocol version 155 m_pSendBuffer[1] = 1; // Stream mode 156 m_pSendBuffer[2] = (m_port >> 8) & 0xFF; // Port in network order 157 m_pSendBuffer[3] = m_port & 0xFF; 158 unsigned char *buf = (unsigned char*)m_pSendBuffer + 4; 159 int i = 0; 160 memset(buf, 0, 4); 161 for (const wxChar* p = ip.c_str(); *p; p++) { 162 const wxChar& c = *p; 163 if (c == '.') { 164 i++; 165 continue; 166 } 167 buf[i] *= 10; 168 buf[i] += c - '0'; 169 } 170 m_pSendBuffer[8] = 0; 171 m_sendBufferLen = 9; 172 m_pRecvBuffer = new char[8]; 173 m_recvBufferLen = 8; 174 m_recvBufferPos = 0; 175 m_handshakeState = socks4_handshake; 176 } 137 177 else 138 178 { 139 179 m_pSendBuffer = new char[4]; … … 321 361 CSocketEventDispatcher::Get().SendEvent(evt); 322 362 return; 323 363 } 364 case socks4_handshake: 365 while (m_recvBufferLen && m_can_read && m_proxyState == handshake) 366 { 367 int read_error; 368 int read = m_pSocket->Read(m_pRecvBuffer + m_recvBufferPos, m_recvBufferLen, read_error); 369 if (read == -1) 370 { 371 if (read_error != EAGAIN) 372 { 373 m_proxyState = noconn; 374 CSocketEvent *evt = new CSocketEvent(m_pEvtHandler, this, CSocketEvent::close, read_error); 375 CSocketEventDispatcher::Get().SendEvent(evt); 376 } 377 else 378 m_can_read = false; 379 return; 380 } 381 382 if (!read) 383 { 384 m_proxyState = noconn; 385 CSocketEvent *evt = new CSocketEvent(m_pEvtHandler, this, CSocketEvent::close, ECONNABORTED); 386 CSocketEventDispatcher::Get().SendEvent(evt); 387 return; 388 } 389 m_recvBufferPos += read; 390 m_recvBufferLen -= read; 391 392 if (m_recvBufferLen) 393 continue; 394 395 m_recvBufferPos = 0; 396 397 if (m_pRecvBuffer[1] != 0x5A) { 398 wxString error; 399 switch (m_pRecvBuffer[1]) { 400 case 0x5B: 401 error = _("Request rejected or failed"); 402 break; 403 case 0x5C: 404 error = _("Request failed - client is not running identd (or not reachable from server)"); 405 break; 406 case 0x5D: 407 error = _("Request failed - client's identd could not confirm the user ID string"); 408 break; 409 default: 410 error.Printf(_("Unassigned error code %d"), (int)(unsigned char) m_pRecvBuffer[1]); 411 break; 412 } 413 m_pOwner->LogMessage(Error, _("Proxy request failed: %s"), error.c_str()); 414 m_proxyState = noconn; 415 CSocketEventDispatcher::Get() 416 .SendEvent(new CSocketEvent(m_pEvtHandler, this, CSocketEvent::close, ECONNABORTED)); 417 return; 418 } 419 m_proxyState = conn; 420 CSocketEventDispatcher::Get() 421 .SendEvent(new CSocketEvent(m_pEvtHandler, this, CSocketEvent::connection, 0)); 422 } 423 return; 324 424 case socks5_method: 325 425 case socks5_auth: 326 426 case socks5_request: -
src/engine/proxy.h
diff -r c915a6d4a543 -r a312537b5789 src/engine/proxy.h
a b 22 22 unknown, 23 23 HTTP, 24 24 SOCKS5, 25 SOCKS4, 25 26 26 27 proxytype_count 27 28 }; -
src/engine/sftpcontrolsocket.cpp
diff -r c915a6d4a543 -r a312537b5789 src/engine/sftpcontrolsocket.cpp
a b 549 549 case CProxySocket::SOCKS5: 550 550 type = 2; 551 551 break; 552 case CProxySocket::SOCKS4: 553 type = 3; 554 break; 552 555 default: 553 556 LogMessage(__TFILE__, __LINE__, this, Debug_Warning, _T("Unsupported proxy type")); 554 557 DoClose(FZ_REPLY_INTERNALERROR); -
src/interface/resources/settings.xrc
diff -r c915a6d4a543 -r a312537b5789 src/interface/resources/settings.xrc
a b 706 706 </object> 707 707 </object> 708 708 <object class="sizeritem"> 709 <object class="wxRadioButton" name="ID_PROXYTYPE_SOCKS4"> 710 <label>SOC&KS 4</label> 711 </object> 712 </object> 713 <object class="sizeritem"> 709 714 <object class="wxRadioButton" name="ID_PROXYTYPE_SOCKS5"> 710 715 <label>&SOCKS 5</label> 711 716 </object> -
src/interface/settings/optionspage_proxy.cpp
diff -r c915a6d4a543 -r a312537b5789 src/interface/settings/optionspage_proxy.cpp
a b 8 8 BEGIN_EVENT_TABLE(COptionsPageProxy, COptionsPageProxy::COptionsPage) 9 9 EVT_RADIOBUTTON(XRCID("ID_PROXYTYPE_NONE"), COptionsPageProxy::OnProxyTypeChanged) 10 10 EVT_RADIOBUTTON(XRCID("ID_PROXYTYPE_HTTP"), COptionsPageProxy::OnProxyTypeChanged) 11 EVT_RADIOBUTTON(XRCID("ID_PROXYTYPE_SOCKS4"), COptionsPageProxy::OnProxyTypeChanged) 11 12 EVT_RADIOBUTTON(XRCID("ID_PROXYTYPE_SOCKS5"), COptionsPageProxy::OnProxyTypeChanged) 12 13 END_EVENT_TABLE() 13 14 … … 33 34 case 2: 34 35 SetRCheck(XRCID("ID_PROXYTYPE_SOCKS5"), true, failure); 35 36 break; 37 case 3: 38 SetRCheck(XRCID("ID_PROXYTYPE_SOCKS4"), true, failure); 39 break; 36 40 } 37 41 38 42 if (!failure) … … 53 57 type = 1; 54 58 else if (GetRCheck(XRCID("ID_PROXYTYPE_SOCKS5"))) 55 59 type = 2; 60 else if (GetRCheck(XRCID("ID_PROXYTYPE_SOCKS4"))) 61 type = 3; 56 62 else 57 63 type = 0; 58 64 m_pOptions->SetOption(OPTION_PROXY_TYPE, type); … … 87 93 void COptionsPageProxy::SetCtrlState() 88 94 { 89 95 bool enabled = XRCCTRL(*this, "ID_PROXYTYPE_NONE", wxRadioButton)->GetValue() == 0; 96 bool enabled_auth = XRCCTRL(*this, "ID_PROXYTYPE_SOCKS4", wxRadioButton)->GetValue() == 0; 90 97 91 98 XRCCTRL(*this, "ID_PROXY_HOST", wxTextCtrl)->Enable(enabled); 92 99 XRCCTRL(*this, "ID_PROXY_PORT", wxTextCtrl)->Enable(enabled); 93 XRCCTRL(*this, "ID_PROXY_USER", wxTextCtrl)->Enable(enabled );94 XRCCTRL(*this, "ID_PROXY_PASS", wxTextCtrl)->Enable(enabled );100 XRCCTRL(*this, "ID_PROXY_USER", wxTextCtrl)->Enable(enabled && enabled_auth); 101 XRCCTRL(*this, "ID_PROXY_PASS", wxTextCtrl)->Enable(enabled && enabled_auth); 95 102 } 96 103 97 104 void COptionsPageProxy::OnProxyTypeChanged(wxCommandEvent& event)