AsyncProxySocketLayer.cpp 28 KB

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