AsyncProxySocketLayer.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  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. 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. CString status;
  485. status.Format(L"HTTP proxy response: %s", UnicodeString(m_pStrBuffer).c_str());
  486. LogSocketMessageRaw(FZ_LOG_PROGRESS, status);
  487. char *pos2 = strstr(m_pStrBuffer, " ");
  488. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  489. {
  490. char *tmp = new char[pos-m_pStrBuffer + 1];
  491. tmp[pos-m_pStrBuffer] = 0;
  492. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  493. ConnectionFailed(WSAECONNABORTED, tmp);
  494. return;
  495. }
  496. }
  497. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  498. {
  499. ConnectionEstablished();
  500. return;
  501. }
  502. }
  503. }
  504. }
  505. void CAsyncProxySocketLayer::ConnectionFailed(int nErrorCode, char * Str)
  506. {
  507. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, Str);
  508. if (m_nProxyOpID == PROXYOP_CONNECT)
  509. {
  510. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  511. }
  512. else
  513. {
  514. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  515. }
  516. Reset();
  517. ClearBuffer();
  518. }
  519. void CAsyncProxySocketLayer::ConnectionEstablished()
  520. {
  521. int Event = (m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT;
  522. ClearBuffer();
  523. Reset();
  524. TriggerEvent(Event, 0, TRUE);
  525. TriggerEvent(FD_READ, 0, TRUE);
  526. TriggerEvent(FD_WRITE, 0, TRUE);
  527. }
  528. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  529. {
  530. if (!m_ProxyData.nProxyType)
  531. //Connect normally because there is no proxy
  532. return ConnectNext(lpszHostAddress, nHostPort);
  533. USES_CONVERSION;
  534. //Translate the host address
  535. DebugAssert(lpszHostAddress != NULL);
  536. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  537. {
  538. // We can send hostname to proxy, no need to resolve it
  539. //Connect to proxy server
  540. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  541. if (!res)
  542. {
  543. if (WSAGetLastError() != WSAEWOULDBLOCK)
  544. {
  545. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  546. return FALSE;
  547. }
  548. }
  549. m_nProxyPeerPort = htons((u_short)nHostPort);
  550. m_nProxyPeerIp = 0;
  551. delete [] m_pProxyPeerHost;
  552. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  553. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  554. m_nProxyOpID=PROXYOP_CONNECT;
  555. return TRUE;
  556. }
  557. SOCKADDR_IN sockAddr;
  558. memset(&sockAddr,0,sizeof(sockAddr));
  559. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  560. sockAddr.sin_family = AF_INET;
  561. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  562. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  563. {
  564. LPHOSTENT lphost;
  565. lphost = gethostbyname(lpszAscii);
  566. if (lphost != NULL)
  567. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  568. else
  569. {
  570. //Can't resolve hostname
  571. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  572. WSASetLastError(WSAEINVAL);
  573. return FALSE;
  574. }
  575. }
  576. sockAddr.sin_port = htons((u_short)nHostPort);
  577. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  578. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  579. {
  580. delete [] m_pProxyPeerHost;
  581. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  582. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  583. }
  584. return res;
  585. }
  586. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  587. {
  588. if (!m_ProxyData.nProxyType)
  589. {
  590. //Connect normally because there is no proxy
  591. return ConnectNext(lpSockAddr, nSockAddrLen );
  592. }
  593. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  594. //Save server details
  595. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  596. m_nProxyPeerPort=sockAddr->sin_port;
  597. delete [] m_pProxyPeerHost;
  598. m_pProxyPeerHost = NULL;
  599. m_nProxyOpID=PROXYOP_CONNECT;
  600. USES_CONVERSION;
  601. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  602. if (!res)
  603. {
  604. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  605. {
  606. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  607. return FALSE;
  608. }
  609. }
  610. return res;
  611. }
  612. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  613. {
  614. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  615. {
  616. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  617. return;
  618. }
  619. DebugAssert(m_nProxyOpID);
  620. if (!m_nProxyOpID)
  621. {
  622. //This should not happen
  623. return;
  624. };
  625. if (nErrorCode)
  626. { //Can't connect to proxy
  627. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  628. if (m_nProxyOpID==PROXYOP_CONNECT)
  629. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  630. else
  631. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  632. Reset();
  633. ClearBuffer();
  634. return;
  635. }
  636. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  637. {
  638. if (m_nProxyOpState)
  639. //Somehow OnConnect has been called more than once
  640. return;
  641. DebugAssert(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  642. ClearBuffer();
  643. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOERROR, 0);
  644. //Send the initial request
  645. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  646. { //SOCKS4 proxy
  647. //Send request
  648. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  649. char *command=new char [9+strlen(lpszAscii)+1];
  650. memset(command,0,9+strlen(lpszAscii)+1);
  651. int len=9;
  652. command[0]=4;
  653. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  654. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  655. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  656. {
  657. DebugAssert(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  658. DebugAssert(strcmp(lpszAscii, ""));
  659. //Set the IP to 0.0.0.x (x is nonzero)
  660. command[4]=0;
  661. command[5]=0;
  662. command[6]=0;
  663. command[7]=1;
  664. //Add host as URL
  665. strcpy(&command[9],lpszAscii);
  666. len+=strlen(lpszAscii)+1;
  667. }
  668. else
  669. memcpy(&command[4],&m_nProxyPeerIp,4);
  670. int res=SendNext(command,len); //Send command
  671. delete [] command;
  672. int nErrorCode=WSAGetLastError();
  673. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  674. {
  675. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  676. return;
  677. }
  678. else if (res<len)
  679. {
  680. ConnectionFailed(WSAECONNABORTED);
  681. return;
  682. }
  683. }
  684. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  685. { //SOCKS5 proxy
  686. //Send initialization request
  687. unsigned char command[10];
  688. memset(command,0,10);
  689. command[0]=5;
  690. //CAsyncProxySocketLayer supports to logon types: No logon and
  691. //cleartext username/password (if set) logon
  692. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  693. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  694. int len=m_ProxyData.bUseLogon?4:3; //length of request
  695. int res=SendNext(command,len);
  696. int nErrorCode=WSAGetLastError();
  697. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  698. {
  699. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  700. return;
  701. }
  702. else if (res<len)
  703. {
  704. ConnectionFailed(WSAECONNABORTED);
  705. return;
  706. }
  707. }
  708. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  709. {
  710. char str[4096]; //This should be large enough
  711. char * pHost = NULL;
  712. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  713. {
  714. pHost = new char[strlen(m_pProxyPeerHost)+1];
  715. strcpy(pHost, m_pProxyPeerHost);
  716. }
  717. else
  718. {
  719. pHost = new char[16];
  720. sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  721. }
  722. if (!m_ProxyData.bUseLogon)
  723. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  724. pHost, ntohs(m_nProxyPeerPort));
  725. else
  726. {
  727. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  728. pHost, ntohs(m_nProxyPeerPort));
  729. char userpass[4096];
  730. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  731. AnsiString base64str = EncodeBase64(userpass, strlen(userpass));
  732. strcat(str, "Authorization: Basic ");
  733. strcat(str, base64str.c_str());
  734. strcat(str, "\r\nProxy-Authorization: Basic ");
  735. strcat(str, base64str.c_str());
  736. strcat(str, "\r\n\r\n");
  737. }
  738. delete [] pHost;
  739. USES_CONVERSION;
  740. CString status;
  741. status.Format(L"HTTP proxy command: %s", UnicodeString(str).c_str());
  742. LogSocketMessageRaw(FZ_LOG_PROGRESS, status);
  743. int numsent=SendNext(str, strlen(str) );
  744. int nErrorCode=WSAGetLastError();
  745. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  746. {
  747. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  748. return;
  749. }
  750. else if ( numsent < static_cast<int>( strlen(str) ) )
  751. {
  752. ConnectionFailed(WSAECONNABORTED);
  753. return;
  754. }
  755. m_nProxyOpState++;
  756. return;
  757. }
  758. else
  759. DebugFail();
  760. //Now we'll wait for the response, handled in OnReceive
  761. m_nProxyOpState++;
  762. }
  763. }
  764. void CAsyncProxySocketLayer::ClearBuffer()
  765. {
  766. delete [] m_pStrBuffer;
  767. m_pStrBuffer = NULL;
  768. if (m_pRecvBuffer)
  769. {
  770. delete [] m_pRecvBuffer;
  771. m_pRecvBuffer=0;
  772. }
  773. m_nRecvBufferLen=0;
  774. m_nRecvBufferPos=0;
  775. }
  776. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  777. {
  778. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  779. return ListenNext(nConnectionBacklog);
  780. USES_CONVERSION;
  781. //Connect to proxy server
  782. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  783. if (!res)
  784. {
  785. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  786. {
  787. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  788. return FALSE;
  789. }
  790. }
  791. m_nProxyPeerPort=0;
  792. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  793. m_nProxyOpID=PROXYOP_LISTEN;
  794. return TRUE;
  795. }
  796. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  797. {
  798. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  799. {
  800. return GetPeerNameNext(rPeerAddress, rPeerPort);
  801. }
  802. if (GetLayerState()==notsock)
  803. {
  804. WSASetLastError(WSAENOTSOCK);
  805. return FALSE;
  806. }
  807. else if (GetLayerState()!=connected)
  808. {
  809. WSASetLastError(WSAENOTCONN);
  810. return FALSE;
  811. }
  812. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  813. {
  814. WSASetLastError(WSAENOTCONN);
  815. return FALSE;
  816. }
  817. DebugAssert(m_ProxyData.nProxyType);
  818. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  819. if (res)
  820. {
  821. rPeerPort=ntohs(m_nProxyPeerPort);
  822. rPeerAddress.Format(L"%d.%d.%d.%d", m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  823. }
  824. return res;
  825. }
  826. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  827. {
  828. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  829. {
  830. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  831. }
  832. if (GetLayerState()==notsock)
  833. {
  834. WSASetLastError(WSAENOTSOCK);
  835. return FALSE;
  836. }
  837. else if (GetLayerState()!=connected)
  838. {
  839. WSASetLastError(WSAENOTCONN);
  840. return FALSE;
  841. }
  842. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  843. {
  844. WSASetLastError(WSAENOTCONN);
  845. return FALSE;
  846. }
  847. DebugAssert(m_ProxyData.nProxyType);
  848. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  849. if (res)
  850. {
  851. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  852. addr->sin_port=m_nProxyPeerPort;
  853. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  854. }
  855. return res;
  856. }
  857. void CAsyncProxySocketLayer::Close()
  858. {
  859. delete [] m_ProxyData.pProxyHost;
  860. delete [] m_ProxyData.pProxyUser;
  861. delete [] m_ProxyData.pProxyPass;
  862. delete [] m_pProxyPeerHost;
  863. m_ProxyData.pProxyHost = NULL;
  864. m_ProxyData.pProxyUser = NULL;
  865. m_ProxyData.pProxyPass = NULL;
  866. m_pProxyPeerHost = NULL;
  867. ClearBuffer();
  868. Reset();
  869. CloseNext();
  870. }
  871. void CAsyncProxySocketLayer::Reset()
  872. {
  873. m_nProxyOpState=0;
  874. m_nProxyOpID=0;
  875. }
  876. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  877. {
  878. if (m_nProxyOpID)
  879. {
  880. WSASetLastError(WSAEWOULDBLOCK);
  881. return SOCKET_ERROR;
  882. }
  883. return SendNext(lpBuf, nBufLen, nFlags);
  884. }
  885. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  886. {
  887. if (m_nProxyOpID)
  888. {
  889. WSASetLastError(WSAEWOULDBLOCK);
  890. return SOCKET_ERROR;
  891. }
  892. return ReceiveNext(lpBuf, nBufLen, nFlags);
  893. }
  894. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  895. {
  896. if (!m_ProxyData.nProxyType)
  897. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  898. GetPeerName(lpSockAddr, lpSockAddrLen);
  899. return TRUE;
  900. }