AsyncProxySocketLayer.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. // CAsyncProxySocketLayer by Tim Kosse ([email protected])
  2. // Version 1.6 (2003-03-26)
  3. //---------------------------------------------------------------------------
  4. // Feel free to use this class, as long as you don't claim that you wrote it
  5. // and this copyright notice stays intact in the source files.
  6. // If you use this class in commercial applications, please send a short message
  7. // to [email protected]
  8. //---------------------------------------------------------------------------
  9. #include "FileZillaPCH.h"
  10. #include "AsyncProxySocketLayer.h"
  11. #include "atlconv.h" //Unicode<->Ascii conversion macros declared here
  12. #include <Soap.EncdDecd.hpp>
  13. //////////////////////////////////////////////////////////////////////
  14. // Konstruktion/Destruktion
  15. //////////////////////////////////////////////////////////////////////
  16. CAsyncProxySocketLayer::CAsyncProxySocketLayer()
  17. {
  18. m_nProxyOpID=0;
  19. m_nProxyOpState=0;
  20. m_pRecvBuffer=0;
  21. m_nRecvBufferLen=0;
  22. m_nRecvBufferPos=0;
  23. m_ProxyData.nProxyType=0;
  24. m_nProxyPeerIp=0;
  25. m_nProxyPeerPort=0;
  26. m_pProxyPeerHost = NULL;
  27. m_pStrBuffer = NULL;
  28. m_ProxyData.pProxyHost = NULL;
  29. m_ProxyData.pProxyUser = NULL;
  30. m_ProxyData.pProxyPass = NULL;
  31. m_pProxyPeerHost = NULL;
  32. }
  33. CAsyncProxySocketLayer::~CAsyncProxySocketLayer()
  34. {
  35. delete [] m_ProxyData.pProxyHost;
  36. delete [] m_ProxyData.pProxyUser;
  37. delete [] m_ProxyData.pProxyPass;
  38. delete [] m_pProxyPeerHost;
  39. ClearBuffer();
  40. }
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Member-Funktion CAsyncProxySocketLayer
  43. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, bool bUseLogon, const char * pProxyUser, const char * pProxyPass)
  44. {
  45. //Validate the parameters
  46. DebugAssert(!m_nProxyOpID);
  47. DebugAssert(pProxyHost && *pProxyHost);
  48. DebugAssert(ProxyPort>0);
  49. DebugAssert(ProxyPort<=65535);
  50. delete m_ProxyData.pProxyHost;
  51. delete m_ProxyData.pProxyUser;
  52. delete m_ProxyData.pProxyPass;
  53. m_ProxyData.pProxyUser = NULL;
  54. m_ProxyData.pProxyPass = NULL;
  55. m_ProxyData.nProxyType = nProxyType;
  56. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  57. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  58. m_ProxyData.nProxyPort=ProxyPort;
  59. if (pProxyUser)
  60. {
  61. m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
  62. strcpy(m_ProxyData.pProxyUser, pProxyUser);
  63. }
  64. if (pProxyPass)
  65. {
  66. m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
  67. strcpy(m_ProxyData.pProxyPass, pProxyPass);
  68. }
  69. m_ProxyData.bUseLogon = bUseLogon;
  70. }
  71. void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
  72. {
  73. //Here we handle the responses from the SOCKS proxy
  74. if (!m_nProxyOpID)
  75. {
  76. TriggerEvent(FD_READ, nErrorCode, TRUE);
  77. return;
  78. }
  79. if (nErrorCode)
  80. {
  81. TriggerEvent(FD_READ, nErrorCode, TRUE);
  82. }
  83. if (!m_nProxyOpState) //We should not receive a response yet!
  84. {
  85. //Ignore it
  86. return;
  87. }
  88. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  89. {
  90. if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
  91. {
  92. if (!m_pRecvBuffer)
  93. m_pRecvBuffer=new char[8];
  94. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-m_nRecvBufferPos);
  95. if (numread==SOCKET_ERROR)
  96. {
  97. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  98. {
  99. ConnectionFailed(WSAGetLastError());
  100. }
  101. return;
  102. }
  103. m_nRecvBufferPos+=numread;
  104. if (m_nRecvBufferPos==8)
  105. {
  106. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  107. {
  108. ConnectionFailed(WSAECONNABORTED);
  109. return;
  110. }
  111. if (m_nProxyOpID==PROXYOP_CONNECT)
  112. {
  113. //OK, we are connected with the remote server
  114. ConnectionEstablished();
  115. return;
  116. }
  117. else
  118. {
  119. //Listen socket created
  120. m_nProxyOpState++;
  121. unsigned long ip;
  122. int port;
  123. memcpy(&ip,&m_pRecvBuffer[4],4);
  124. if (!ip)
  125. {
  126. //No IP return, use the IP of the proxy server
  127. SOCKADDR SockAddr;
  128. memset(&SockAddr,0,sizeof(SockAddr));
  129. int SockAddrLen=sizeof(SockAddr);
  130. if (GetPeerName(&SockAddr, &SockAddrLen ))
  131. {
  132. ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
  133. }
  134. else
  135. {
  136. ConnectionFailed(WSAECONNABORTED);
  137. return;
  138. }
  139. }
  140. memcpy(&port,&m_pRecvBuffer[2],2);
  141. t_ListenSocketCreatedStruct data;
  142. data.ip=ip;
  143. data.nPort=port;
  144. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  145. }
  146. ClearBuffer();
  147. }
  148. }
  149. else if (m_nProxyOpID==PROXYOP_LISTEN)
  150. {
  151. if (!m_pRecvBuffer)
  152. m_pRecvBuffer=new char[8];
  153. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-m_nRecvBufferPos);
  154. if (numread==SOCKET_ERROR)
  155. {
  156. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  157. {
  158. ConnectionFailed(WSAGetLastError());
  159. }
  160. return;
  161. }
  162. m_nRecvBufferPos+=numread;
  163. if (m_nRecvBufferPos==8)
  164. {
  165. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  166. {
  167. ConnectionFailed(WSAECONNABORTED);
  168. return;
  169. }
  170. //Connection to remote server established
  171. ConnectionEstablished();
  172. }
  173. }
  174. }
  175. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  176. {
  177. if (m_nProxyOpState==1) //Get respone to initialization message
  178. {
  179. if (!m_pRecvBuffer)
  180. m_pRecvBuffer=new char[2];
  181. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,2-m_nRecvBufferPos);
  182. if (numread==SOCKET_ERROR)
  183. {
  184. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  185. {
  186. ConnectionFailed(WSAGetLastError());
  187. }
  188. return;
  189. }
  190. m_nRecvBufferPos+=numread;
  191. if (m_nRecvBufferPos==2)
  192. {
  193. if (m_pRecvBuffer[0]!=5)
  194. {
  195. ConnectionFailed(WSAECONNABORTED);
  196. return;
  197. }
  198. if (m_pRecvBuffer[1])
  199. {
  200. //Auth needed
  201. if (m_pRecvBuffer[1]!=2)
  202. {
  203. //Unknown auth type
  204. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
  205. if (m_nProxyOpID==PROXYOP_CONNECT)
  206. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  207. else
  208. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  209. Reset();
  210. ClearBuffer();
  211. return;
  212. }
  213. if (!m_ProxyData.bUseLogon)
  214. {
  215. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
  216. if (m_nProxyOpID==PROXYOP_CONNECT)
  217. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  218. else
  219. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  220. Reset();
  221. ClearBuffer();
  222. return;
  223. }
  224. //Send authentication
  225. LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
  226. LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
  227. DebugAssert(strlen(lpszAsciiUser)<=255);
  228. DebugAssert(strlen(lpszAsciiPass)<=255);
  229. unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
  230. sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
  231. buffer[0]=1;
  232. buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
  233. buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
  234. int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
  235. int res=SendNext(buffer,len);
  236. delete [] buffer;
  237. if (res==SOCKET_ERROR || res<len)
  238. {
  239. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  240. {
  241. ConnectionFailed(WSAGetLastError());
  242. return;
  243. }
  244. }
  245. ClearBuffer();
  246. m_nProxyOpState++;
  247. return;
  248. }
  249. }
  250. //No auth needed
  251. //Send connection request
  252. const char *lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  253. char *command=new char[10+strlen(lpszAsciiHost)+1];
  254. memset(command,0,10+strlen(lpszAsciiHost)+1);
  255. command[0]=5;
  256. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  257. command[2]=0;
  258. command[3]=m_nProxyPeerIp?1:3;
  259. int len=4;
  260. if (m_nProxyPeerIp)
  261. {
  262. memcpy(&command[len],&m_nProxyPeerIp,4);
  263. len+=4;
  264. }
  265. else
  266. {
  267. command[len]=strlen(lpszAsciiHost);
  268. strcpy(&command[len+1], lpszAsciiHost);
  269. len += strlen(lpszAsciiHost) + 1;
  270. }
  271. memcpy(&command[len], &m_nProxyPeerPort, 2);
  272. len+=2;
  273. int res=SendNext(command,len);
  274. delete [] command;
  275. if (res==SOCKET_ERROR || res<len)
  276. {
  277. if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  278. {
  279. ConnectionFailed(WSAGetLastError());
  280. return;
  281. }
  282. }
  283. m_nProxyOpState+=2;
  284. ClearBuffer();
  285. return;
  286. }
  287. else if (m_nProxyOpState==2)
  288. {
  289. //Response to the auth request
  290. if (!m_pRecvBuffer)
  291. m_pRecvBuffer=new char[2];
  292. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
  293. if (numread==SOCKET_ERROR)
  294. {
  295. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  296. {
  297. ConnectionFailed(WSAGetLastError());
  298. }
  299. return;
  300. }
  301. m_nRecvBufferPos+=numread;
  302. if (m_nRecvBufferPos==2)
  303. {
  304. if (m_pRecvBuffer[1]!=0)
  305. {
  306. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
  307. if (m_nProxyOpID==PROXYOP_CONNECT)
  308. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  309. else
  310. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  311. Reset();
  312. ClearBuffer();
  313. return;
  314. }
  315. const char * lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  316. char *command = new char[10+strlen(lpszAsciiHost)+1];
  317. memset(command,0,10+strlen(lpszAsciiHost)+1);
  318. command[0]=5;
  319. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  320. command[2]=0;
  321. command[3]=m_nProxyPeerIp?1:3;
  322. int len=4;
  323. if (m_nProxyPeerIp)
  324. {
  325. memcpy(&command[len],&m_nProxyPeerIp,4);
  326. len+=4;
  327. }
  328. else
  329. {
  330. command[len]=strlen(lpszAsciiHost);
  331. strcpy(&command[len+1],lpszAsciiHost);
  332. len+=strlen(lpszAsciiHost)+1;
  333. }
  334. memcpy(&command[len],&m_nProxyPeerPort,2);
  335. len+=2;
  336. int res=SendNext(command,len);
  337. delete [] command;
  338. if (res==SOCKET_ERROR || res<len)
  339. {
  340. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  341. {
  342. ConnectionFailed(WSAGetLastError());
  343. return;
  344. }
  345. }
  346. m_nProxyOpState++;
  347. ClearBuffer();
  348. return;
  349. }
  350. }
  351. else if (m_nProxyOpState==3)
  352. {
  353. //Response to the connection request
  354. if (!m_pRecvBuffer)
  355. {
  356. m_pRecvBuffer=new char[10];
  357. m_nRecvBufferLen=5;
  358. }
  359. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
  360. if (numread==SOCKET_ERROR)
  361. {
  362. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  363. {
  364. ConnectionFailed(WSAGetLastError());
  365. }
  366. return;
  367. }
  368. m_nRecvBufferPos+=numread;
  369. if (m_nRecvBufferPos==m_nRecvBufferLen)
  370. {
  371. //Check for errors
  372. if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
  373. {
  374. ConnectionFailed(WSAECONNABORTED);
  375. return;
  376. }
  377. if (m_nRecvBufferLen==5)
  378. {
  379. //Check which kind of address the response contains
  380. if (m_pRecvBuffer[3]==1)
  381. m_nRecvBufferLen=10;
  382. else
  383. {
  384. char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
  385. memcpy(tmp,m_pRecvBuffer,5);
  386. delete [] m_pRecvBuffer;
  387. m_pRecvBuffer=tmp;
  388. m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
  389. }
  390. return;
  391. }
  392. if (m_nProxyOpID==PROXYOP_CONNECT)
  393. {
  394. //OK, we are connected with the remote server
  395. ConnectionEstablished();
  396. }
  397. else
  398. {
  399. //Listen socket created
  400. m_nProxyOpState++;
  401. unsigned long ip;
  402. unsigned short port;
  403. DebugAssert(m_pRecvBuffer[3]==1);
  404. memcpy(&ip, &m_pRecvBuffer[4], 4);
  405. memcpy(&port, &m_pRecvBuffer[8], 2);
  406. t_ListenSocketCreatedStruct data;
  407. data.ip=ip;
  408. data.nPort=port;
  409. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  410. }
  411. ClearBuffer();
  412. }
  413. }
  414. else if (m_nProxyOpState==4)
  415. {
  416. DebugAssert(m_nProxyOpID == PROXYOP_LISTEN);
  417. if (!m_pRecvBuffer)
  418. m_pRecvBuffer=new char[10];
  419. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
  420. if (numread==SOCKET_ERROR)
  421. {
  422. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  423. {
  424. ConnectionFailed(WSAGetLastError());
  425. }
  426. return;
  427. }
  428. m_nRecvBufferPos+=numread;
  429. if (m_nRecvBufferPos==10)
  430. {
  431. if (m_pRecvBuffer[1]!=0)
  432. {
  433. ConnectionFailed(WSAECONNABORTED);
  434. return;
  435. }
  436. //Connection to remote server established
  437. ConnectionEstablished();
  438. }
  439. }
  440. }
  441. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  442. {
  443. DebugAssert(m_nProxyOpID==PROXYOP_CONNECT);
  444. char buffer[9]={0};
  445. bool responseLogged = false;
  446. for(;;)
  447. {
  448. int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
  449. if (numread==SOCKET_ERROR)
  450. {
  451. int nError=WSAGetLastError();
  452. if (nError!=WSAEWOULDBLOCK)
  453. {
  454. ConnectionFailed(nError);
  455. }
  456. return;
  457. }
  458. //Response begins with HTTP/
  459. if (!m_pStrBuffer)
  460. {
  461. m_pStrBuffer = new char[strlen(buffer) + 1];
  462. strcpy(m_pStrBuffer, buffer);
  463. }
  464. else
  465. {
  466. char *tmp = m_pStrBuffer;
  467. m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
  468. strcpy(m_pStrBuffer, tmp);
  469. strcpy(m_pStrBuffer + strlen(tmp), buffer);
  470. delete [] tmp;
  471. }
  472. memset(buffer, 0, 9);
  473. const char start[] = "HTTP/";
  474. if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
  475. {
  476. char* str = new char[strlen("No valid HTTP response") + 1];
  477. strcpy(str, "No valid HTTP response");
  478. ConnectionFailed(WSAECONNABORTED, str);
  479. return;
  480. }
  481. char *pos = strstr(m_pStrBuffer, "\r\n");
  482. if (pos)
  483. {
  484. if (!responseLogged)
  485. {
  486. CString status;
  487. status.Format(L"HTTP proxy response: %s", UnicodeString(m_pStrBuffer, pos - m_pStrBuffer).c_str());
  488. LogSocketMessageRaw(FZ_LOG_PROGRESS, status);
  489. responseLogged = true;
  490. }
  491. char *pos2 = strstr(m_pStrBuffer, " ");
  492. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  493. {
  494. char *tmp = new char[pos-m_pStrBuffer + 1];
  495. tmp[pos-m_pStrBuffer] = 0;
  496. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  497. ConnectionFailed(WSAECONNABORTED, tmp);
  498. return;
  499. }
  500. }
  501. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  502. {
  503. CString status;
  504. status.Format(L"HTTP proxy headers: %s", UnicodeString(pos).c_str());
  505. LogSocketMessageRaw(FZ_LOG_PROGRESS, status);
  506. ConnectionEstablished();
  507. return;
  508. }
  509. }
  510. }
  511. }
  512. void CAsyncProxySocketLayer::ConnectionFailed(int nErrorCode, char * Str)
  513. {
  514. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, Str);
  515. if (m_nProxyOpID == PROXYOP_CONNECT)
  516. {
  517. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  518. }
  519. else
  520. {
  521. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  522. }
  523. Reset();
  524. ClearBuffer();
  525. }
  526. void CAsyncProxySocketLayer::ConnectionEstablished()
  527. {
  528. int Event = (m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT;
  529. ClearBuffer();
  530. Reset();
  531. TriggerEvent(Event, 0, TRUE);
  532. TriggerEvent(FD_READ, 0, TRUE);
  533. TriggerEvent(FD_WRITE, 0, TRUE);
  534. }
  535. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  536. {
  537. if (!m_ProxyData.nProxyType)
  538. //Connect normally because there is no proxy
  539. return ConnectNext(lpszHostAddress, nHostPort);
  540. USES_CONVERSION;
  541. //Translate the host address
  542. DebugAssert(lpszHostAddress != NULL);
  543. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  544. {
  545. // We can send hostname to proxy, no need to resolve it
  546. //Connect to proxy server
  547. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  548. if (!res)
  549. {
  550. if (WSAGetLastError() != WSAEWOULDBLOCK)
  551. {
  552. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  553. return FALSE;
  554. }
  555. }
  556. m_nProxyPeerPort = htons((u_short)nHostPort);
  557. m_nProxyPeerIp = 0;
  558. delete [] m_pProxyPeerHost;
  559. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  560. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  561. m_nProxyOpID=PROXYOP_CONNECT;
  562. return TRUE;
  563. }
  564. SOCKADDR_IN sockAddr;
  565. memset(&sockAddr,0,sizeof(sockAddr));
  566. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  567. sockAddr.sin_family = AF_INET;
  568. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  569. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  570. {
  571. LPHOSTENT lphost;
  572. lphost = gethostbyname(lpszAscii);
  573. if (lphost != NULL)
  574. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  575. else
  576. {
  577. //Can't resolve hostname
  578. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  579. WSASetLastError(WSAEINVAL);
  580. return FALSE;
  581. }
  582. }
  583. sockAddr.sin_port = htons((u_short)nHostPort);
  584. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  585. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  586. {
  587. delete [] m_pProxyPeerHost;
  588. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  589. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  590. }
  591. return res;
  592. }
  593. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  594. {
  595. if (!m_ProxyData.nProxyType)
  596. {
  597. //Connect normally because there is no proxy
  598. return ConnectNext(lpSockAddr, nSockAddrLen );
  599. }
  600. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  601. //Save server details
  602. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  603. m_nProxyPeerPort=sockAddr->sin_port;
  604. delete [] m_pProxyPeerHost;
  605. m_pProxyPeerHost = NULL;
  606. m_nProxyOpID=PROXYOP_CONNECT;
  607. USES_CONVERSION;
  608. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  609. if (!res)
  610. {
  611. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  612. {
  613. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  614. return FALSE;
  615. }
  616. }
  617. return res;
  618. }
  619. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  620. {
  621. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  622. {
  623. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  624. return;
  625. }
  626. DebugAssert(m_nProxyOpID);
  627. if (!m_nProxyOpID)
  628. {
  629. //This should not happen
  630. return;
  631. };
  632. if (nErrorCode)
  633. { //Can't connect to proxy
  634. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  635. if (m_nProxyOpID==PROXYOP_CONNECT)
  636. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  637. else
  638. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  639. Reset();
  640. ClearBuffer();
  641. return;
  642. }
  643. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  644. {
  645. if (m_nProxyOpState)
  646. //Somehow OnConnect has been called more than once
  647. return;
  648. DebugAssert(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  649. ClearBuffer();
  650. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOERROR, 0);
  651. //Send the initial request
  652. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  653. { //SOCKS4 proxy
  654. //Send request
  655. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  656. char *command=new char [9+strlen(lpszAscii)+1];
  657. memset(command,0,9+strlen(lpszAscii)+1);
  658. int len=9;
  659. command[0]=4;
  660. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  661. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  662. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  663. {
  664. DebugAssert(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  665. DebugAssert(strcmp(lpszAscii, ""));
  666. //Set the IP to 0.0.0.x (x is nonzero)
  667. command[4]=0;
  668. command[5]=0;
  669. command[6]=0;
  670. command[7]=1;
  671. //Add host as URL
  672. strcpy(&command[9],lpszAscii);
  673. len+=strlen(lpszAscii)+1;
  674. }
  675. else
  676. memcpy(&command[4],&m_nProxyPeerIp,4);
  677. int res=SendNext(command,len); //Send command
  678. delete [] command;
  679. int nErrorCode=WSAGetLastError();
  680. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  681. {
  682. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  683. return;
  684. }
  685. else if (res<len)
  686. {
  687. ConnectionFailed(WSAECONNABORTED);
  688. return;
  689. }
  690. }
  691. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  692. { //SOCKS5 proxy
  693. //Send initialization request
  694. unsigned char command[10];
  695. memset(command,0,10);
  696. command[0]=5;
  697. //CAsyncProxySocketLayer supports to logon types: No logon and
  698. //cleartext username/password (if set) logon
  699. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  700. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  701. int len=m_ProxyData.bUseLogon?4:3; //length of request
  702. int res=SendNext(command,len);
  703. int nErrorCode=WSAGetLastError();
  704. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  705. {
  706. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  707. return;
  708. }
  709. else if (res<len)
  710. {
  711. ConnectionFailed(WSAECONNABORTED);
  712. return;
  713. }
  714. }
  715. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  716. {
  717. char str[4096]; //This should be large enough
  718. char * pHost = NULL;
  719. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  720. {
  721. pHost = new char[strlen(m_pProxyPeerHost)+1];
  722. strcpy(pHost, m_pProxyPeerHost);
  723. }
  724. else
  725. {
  726. pHost = new char[16];
  727. sprintf(pHost, "%lu.%lu.%lu.%lu", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  728. }
  729. if (!m_ProxyData.bUseLogon)
  730. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  731. pHost, ntohs(m_nProxyPeerPort));
  732. else
  733. {
  734. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  735. pHost, ntohs(m_nProxyPeerPort));
  736. char userpass[4096];
  737. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  738. AnsiString base64str = EncodeBase64(userpass, strlen(userpass));
  739. strcat(str, "Authorization: Basic ");
  740. strcat(str, base64str.c_str());
  741. strcat(str, "\r\nProxy-Authorization: Basic ");
  742. strcat(str, base64str.c_str());
  743. strcat(str, "\r\n\r\n");
  744. }
  745. delete [] pHost;
  746. CString status;
  747. status.Format(L"HTTP proxy command: %s", UnicodeString(str).c_str());
  748. LogSocketMessageRaw(FZ_LOG_PROGRESS, status);
  749. int numsent=SendNext(str, strlen(str) );
  750. int nErrorCode=WSAGetLastError();
  751. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  752. {
  753. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  754. return;
  755. }
  756. else if ( numsent < static_cast<int>( strlen(str) ) )
  757. {
  758. ConnectionFailed(WSAECONNABORTED);
  759. return;
  760. }
  761. m_nProxyOpState++;
  762. return;
  763. }
  764. else
  765. DebugFail();
  766. //Now we'll wait for the response, handled in OnReceive
  767. m_nProxyOpState++;
  768. }
  769. }
  770. void CAsyncProxySocketLayer::ClearBuffer()
  771. {
  772. delete [] m_pStrBuffer;
  773. m_pStrBuffer = NULL;
  774. if (m_pRecvBuffer)
  775. {
  776. delete [] m_pRecvBuffer;
  777. m_pRecvBuffer=0;
  778. }
  779. m_nRecvBufferLen=0;
  780. m_nRecvBufferPos=0;
  781. }
  782. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  783. {
  784. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  785. return ListenNext(nConnectionBacklog);
  786. USES_CONVERSION;
  787. //Connect to proxy server
  788. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  789. if (!res)
  790. {
  791. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  792. {
  793. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  794. return FALSE;
  795. }
  796. }
  797. m_nProxyPeerPort=0;
  798. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  799. m_nProxyOpID=PROXYOP_LISTEN;
  800. return TRUE;
  801. }
  802. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  803. {
  804. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  805. {
  806. return GetPeerNameNext(rPeerAddress, rPeerPort);
  807. }
  808. if (GetLayerState()==notsock)
  809. {
  810. WSASetLastError(WSAENOTSOCK);
  811. return FALSE;
  812. }
  813. else if (GetLayerState()!=connected)
  814. {
  815. WSASetLastError(WSAENOTCONN);
  816. return FALSE;
  817. }
  818. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  819. {
  820. WSASetLastError(WSAENOTCONN);
  821. return FALSE;
  822. }
  823. DebugAssert(m_ProxyData.nProxyType);
  824. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  825. if (res)
  826. {
  827. rPeerPort=ntohs(m_nProxyPeerPort);
  828. rPeerAddress.Format(L"%d.%d.%d.%d", m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  829. }
  830. return res;
  831. }
  832. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  833. {
  834. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  835. {
  836. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  837. }
  838. if (GetLayerState()==notsock)
  839. {
  840. WSASetLastError(WSAENOTSOCK);
  841. return FALSE;
  842. }
  843. else if (GetLayerState()!=connected)
  844. {
  845. WSASetLastError(WSAENOTCONN);
  846. return FALSE;
  847. }
  848. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  849. {
  850. WSASetLastError(WSAENOTCONN);
  851. return FALSE;
  852. }
  853. DebugAssert(m_ProxyData.nProxyType);
  854. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  855. if (res)
  856. {
  857. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  858. addr->sin_port=m_nProxyPeerPort;
  859. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  860. }
  861. return res;
  862. }
  863. void CAsyncProxySocketLayer::Close()
  864. {
  865. delete [] m_ProxyData.pProxyHost;
  866. delete [] m_ProxyData.pProxyUser;
  867. delete [] m_ProxyData.pProxyPass;
  868. delete [] m_pProxyPeerHost;
  869. m_ProxyData.pProxyHost = NULL;
  870. m_ProxyData.pProxyUser = NULL;
  871. m_ProxyData.pProxyPass = NULL;
  872. m_pProxyPeerHost = NULL;
  873. ClearBuffer();
  874. Reset();
  875. CloseNext();
  876. }
  877. void CAsyncProxySocketLayer::Reset()
  878. {
  879. m_nProxyOpState=0;
  880. m_nProxyOpID=0;
  881. }
  882. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  883. {
  884. if (m_nProxyOpID)
  885. {
  886. WSASetLastError(WSAEWOULDBLOCK);
  887. return SOCKET_ERROR;
  888. }
  889. return SendNext(lpBuf, nBufLen, nFlags);
  890. }
  891. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  892. {
  893. if (m_nProxyOpID)
  894. {
  895. WSASetLastError(WSAEWOULDBLOCK);
  896. return SOCKET_ERROR;
  897. }
  898. return ReceiveNext(lpBuf, nBufLen, nFlags);
  899. }
  900. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  901. {
  902. if (!m_ProxyData.nProxyType)
  903. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  904. GetPeerName(lpSockAddr, lpSockAddrLen);
  905. return TRUE;
  906. }