AsyncProxySocketLayer.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. /*CAsyncProxySocketLayer by Tim Kosse ([email protected])
  2. Version 1.6 (2003-03-26)
  3. --------------------------------------------------------
  4. Introduction:
  5. -------------
  6. This class is layer class for CAsyncSocketEx. With this class you
  7. can connect through SOCKS4/5 and HTTP 1.1 proxies. This class works
  8. as semi-transparent layer between CAsyncSocketEx and the actual socket.
  9. This class is used in FileZilla, a powerful open-source FTP client.
  10. It can be found under http://sourceforge.net/projects/filezilla
  11. For more information about SOCKS4/5 goto
  12. http://www.socks.nec.com/socksprot.html
  13. For more information about HTTP 1.1 goto http://www.rfc-editor.org
  14. and search for RFC2616
  15. How to use?
  16. -----------
  17. You don't have to change much in you already existing code to use
  18. CAsyncProxySocketLayer.
  19. To use it, create an instance of CAsyncProxySocketLayer, call SetProxy
  20. and attach it to a CAsyncSocketEx instance.
  21. You have to process OnLayerCallback in you CAsyncSocketEx instance as it will
  22. receive all layer nofications.
  23. The following notifications are sent:
  24. //Error codes
  25. PROXYERROR_NOERROR 0
  26. PROXYERROR_NOCONN 1 //Can't connect to proxy server, use GetLastError for more information
  27. PROXYERROR_REQUESTFAILED 2 //Request failed, can't send data
  28. PROXYERROR_AUTHREQUIRED 3 //Authentication required
  29. PROXYERROR_AUTHTYPEUNKNOWN 4 //Authtype unknown or not supported
  30. PROXYERROR_AUTHFAILED 5 //Authentication failed
  31. PROXYERROR_AUTHNOLOGON 6
  32. PROXYERROR_CANTRESOLVEHOST 7
  33. //Status messages
  34. PROXYSTATUS_LISTENSOCKETCREATED 8 //Called when a listen socket was created successfully. Unlike the normal listen function,
  35. //a socksified socket has to connect to the proxy to negotiate the details with the server
  36. //on which the listen socket will be created
  37. //The two parameters will contain the ip and port of the listen socket on the server.
  38. If you want to use CAsyncProxySocketLayer to create a listen socket, you
  39. have to use this overloaded function:
  40. BOOL PrepareListen(unsigned long serverIp);
  41. serverIP is the IP of the server you are already connected
  42. through the SOCKS proxy. You can't use listen sockets over a
  43. SOCKS proxy without a primary connection. Listen sockets are only
  44. supported by SOCKS proxies, this won't work with HTTP proxies.
  45. When the listen socket is created successfully, the PROXYSTATUS_LISTENSOCKETCREATED
  46. notification is sent. The parameters will tell you the ip and the port of the listen socket.
  47. After it you have to handle the OnAccept message and accept the
  48. connection.
  49. Be carful when calling Accept: rConnected socket will NOT be filled! Instead use the instance which created the
  50. listen socket, it will handle the data connection.
  51. If you want to accept more than one connection, you have to create a listing socket for each of them!
  52. Description of important functions and their parameters:
  53. --------------------------------------------------------
  54. void SetProxy(int nProxyType);
  55. void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort);
  56. void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort, const char *pProxyUser, const char * pProxyPass);
  57. Call one of this functions to set the proxy type.
  58. Parametes:
  59. - nProxyType specifies the Proxy Type.
  60. - ProxyHost and nProxyPort specify the address of the proxy
  61. - ProxyUser and ProxyPass are only available for SOCKS5 proxies.
  62. supported proxy types:
  63. PROXYTYPE_NOPROXY
  64. PROXYTYPE_SOCKS4
  65. PROXYTYPE_SOCKS4A
  66. PROXYTYPE_SOCKS5
  67. PROXYTYPE_HTTP11
  68. There are also some other functions:
  69. GetProxyPeerName
  70. Like GetPeerName of CAsyncSocket, but returns the address of the
  71. server connected through the proxy. If using proxies, GetPeerName
  72. only returns the address of the proxy.
  73. int GetProxyType();
  74. Returns the used proxy
  75. const int GetLastProxyError() const;
  76. Returns the last proxy error
  77. License
  78. -------
  79. Feel free to use this class, as long as you don't claim that you wrote it
  80. and this copyright notice stays intact in the source files.
  81. If you use this class in commercial applications, please send a short message
  82. to [email protected]
  83. Version history
  84. ---------------
  85. - 1.6 got rid of MFC
  86. - 1.5 released CAsyncSocketExLayer version
  87. - 1.4 added UNICODE support
  88. - 1.3 added basic HTTP1.1 authentication
  89. fixed memory leak in SOCKS5 code
  90. OnSocksOperationFailed will be called after Socket has been closed
  91. fixed some minor bugs
  92. - 1.2 renamed into CAsyncProxySocketLayer
  93. added HTTP1.1 proxy support
  94. - 1.1 fixes all known bugs, mostly with SOCKS5 authentication
  95. - 1.0 initial release
  96. */
  97. #include "stdafx.h"
  98. #include "AsyncProxySocketLayer.h"
  99. #include "atlconv.h" //Unicode<->Ascii conversion macros declared here
  100. #include "CBase64coding.hpp"
  101. #ifdef _DEBUG
  102. #undef THIS_FILE
  103. static char THIS_FILE[]=__FILE__;
  104. #define new DEBUG_NEW
  105. #endif
  106. //////////////////////////////////////////////////////////////////////
  107. // Konstruktion/Destruktion
  108. //////////////////////////////////////////////////////////////////////
  109. CAsyncProxySocketLayer::CAsyncProxySocketLayer()
  110. {
  111. m_nProxyOpID=0;
  112. m_nProxyOpState=0;
  113. m_pRecvBuffer=0;
  114. m_nRecvBufferLen=0;
  115. m_nRecvBufferPos=0;
  116. m_ProxyData.nProxyType=0;
  117. m_nProxyPeerIp=0;
  118. m_nProxyPeerPort=0;
  119. m_pProxyPeerHost = NULL;
  120. m_pStrBuffer = NULL;
  121. m_ProxyData.pProxyHost = NULL;
  122. m_ProxyData.pProxyUser = NULL;
  123. m_ProxyData.pProxyPass = NULL;
  124. m_pProxyPeerHost = NULL;
  125. }
  126. CAsyncProxySocketLayer::~CAsyncProxySocketLayer()
  127. {
  128. delete [] m_ProxyData.pProxyHost;
  129. delete [] m_ProxyData.pProxyUser;
  130. delete [] m_ProxyData.pProxyPass;
  131. delete [] m_pProxyPeerHost;
  132. ClearBuffer();
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. // Member-Funktion CAsyncProxySocketLayer
  136. void CAsyncProxySocketLayer::SetProxy(int nProxyType)
  137. {
  138. //Validate the parameters
  139. ASSERT(nProxyType==PROXYTYPE_NOPROXY);
  140. m_ProxyData.nProxyType=nProxyType;
  141. }
  142. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort)
  143. {
  144. USES_CONVERSION;
  145. //Validate the parameters
  146. ASSERT(nProxyType==PROXYTYPE_SOCKS4 ||
  147. nProxyType==PROXYTYPE_SOCKS4A ||
  148. nProxyType==PROXYTYPE_SOCKS5 ||
  149. nProxyType==PROXYTYPE_HTTP11);
  150. ASSERT(!m_nProxyOpID);
  151. ASSERT(pProxyHost && *pProxyHost);
  152. ASSERT(ProxyPort>0);
  153. ASSERT(ProxyPort<=65535);
  154. delete m_ProxyData.pProxyHost;
  155. delete m_ProxyData.pProxyUser;
  156. delete m_ProxyData.pProxyPass;
  157. m_ProxyData.pProxyUser = NULL;
  158. m_ProxyData.pProxyPass = NULL;
  159. m_ProxyData.nProxyType = nProxyType;
  160. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  161. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  162. m_ProxyData.nProxyPort = ProxyPort;
  163. m_ProxyData.bUseLogon = FALSE;
  164. }
  165. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, const char * pProxyUser, const char * pProxyPass)
  166. {
  167. USES_CONVERSION;
  168. //Validate the parameters
  169. ASSERT(nProxyType==PROXYTYPE_SOCKS5 || nProxyType==PROXYTYPE_HTTP11);
  170. ASSERT(!m_nProxyOpID);
  171. ASSERT(pProxyHost && *pProxyHost);
  172. ASSERT(ProxyPort>0);
  173. ASSERT(ProxyPort<=65535);
  174. delete m_ProxyData.pProxyHost;
  175. delete m_ProxyData.pProxyUser;
  176. delete m_ProxyData.pProxyPass;
  177. m_ProxyData.pProxyUser = NULL;
  178. m_ProxyData.pProxyPass = NULL;
  179. m_ProxyData.nProxyType = nProxyType;
  180. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  181. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  182. m_ProxyData.nProxyPort=ProxyPort;
  183. if (pProxyUser)
  184. {
  185. m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
  186. strcpy(m_ProxyData.pProxyUser, pProxyUser);
  187. }
  188. if (pProxyPass)
  189. {
  190. m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
  191. strcpy(m_ProxyData.pProxyPass, pProxyPass);
  192. }
  193. m_ProxyData.bUseLogon = TRUE;
  194. }
  195. void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
  196. {
  197. //Here we handle the responses from the SOCKS proxy
  198. if (!m_nProxyOpID)
  199. {
  200. TriggerEvent(FD_READ, nErrorCode, TRUE);
  201. return;
  202. }
  203. if (nErrorCode)
  204. {
  205. TriggerEvent(FD_READ, nErrorCode, TRUE);
  206. }
  207. if (!m_nProxyOpState) //We should not receive a response yet!
  208. {
  209. //Ignore it
  210. return;
  211. }
  212. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  213. {
  214. if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
  215. {
  216. if (!m_pRecvBuffer)
  217. m_pRecvBuffer=new char[8];
  218. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-m_nRecvBufferPos);
  219. if (numread==SOCKET_ERROR)
  220. {
  221. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  222. {
  223. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  224. if (m_nProxyOpID==PROXYOP_CONNECT)
  225. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  226. else
  227. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  228. Reset();
  229. ClearBuffer();
  230. }
  231. return;
  232. }
  233. m_nRecvBufferPos+=numread;
  234. if (m_nRecvBufferPos==8)
  235. {
  236. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  237. {
  238. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  239. if (m_nProxyOpID==PROXYOP_CONNECT)
  240. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  241. else
  242. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  243. Reset();
  244. ClearBuffer();
  245. return;
  246. }
  247. if (m_nProxyOpID==PROXYOP_CONNECT)
  248. {
  249. //OK, we are connected with the remote server
  250. ClearBuffer();
  251. Reset();
  252. TriggerEvent(FD_CONNECT, 0, TRUE);
  253. TriggerEvent(FD_READ, 0, TRUE);
  254. TriggerEvent(FD_WRITE, 0, TRUE);
  255. return;
  256. }
  257. else
  258. {
  259. //Listen socket created
  260. m_nProxyOpState++;
  261. unsigned long ip;
  262. int port;
  263. memcpy(&ip,&m_pRecvBuffer[4],4);
  264. if (!ip)
  265. {
  266. //No IP return, use the IP of the proxy server
  267. SOCKADDR SockAddr;
  268. memset(&SockAddr,0,sizeof(SockAddr));
  269. int SockAddrLen=sizeof(SockAddr);
  270. if (GetPeerName(&SockAddr, &SockAddrLen ))
  271. {
  272. ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
  273. }
  274. else
  275. {
  276. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  277. if (m_nProxyOpID==PROXYOP_CONNECT)
  278. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  279. else
  280. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  281. Reset();
  282. ClearBuffer();
  283. return;
  284. }
  285. }
  286. memcpy(&port,&m_pRecvBuffer[2],2);
  287. t_ListenSocketCreatedStruct data;
  288. data.ip=ip;
  289. data.nPort=port;
  290. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  291. }
  292. ClearBuffer();
  293. }
  294. }
  295. else if (m_nProxyOpID==2)
  296. {
  297. if (!m_pRecvBuffer)
  298. m_pRecvBuffer=new char[8];
  299. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-m_nRecvBufferPos);
  300. if (numread==SOCKET_ERROR)
  301. {
  302. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  303. {
  304. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  305. if (m_nProxyOpID==PROXYOP_CONNECT)
  306. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  307. else
  308. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  309. Reset();
  310. ClearBuffer();
  311. }
  312. return;
  313. }
  314. m_nRecvBufferPos+=numread;
  315. if (m_nRecvBufferPos==8)
  316. {
  317. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  318. {
  319. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  320. if (m_nProxyOpID==PROXYOP_CONNECT)
  321. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  322. else
  323. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  324. Reset();
  325. ClearBuffer();
  326. return;
  327. }
  328. //Connection to remote server established
  329. ClearBuffer();
  330. Reset();
  331. TriggerEvent(FD_ACCEPT, 0, TRUE);
  332. TriggerEvent(FD_READ, 0, TRUE);
  333. TriggerEvent(FD_WRITE, 0, TRUE);
  334. }
  335. }
  336. }
  337. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  338. {
  339. if (m_nProxyOpState==1) //Get respone to initialization message
  340. {
  341. if (!m_pRecvBuffer)
  342. m_pRecvBuffer=new char[2];
  343. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,2-m_nRecvBufferPos);
  344. if (numread==SOCKET_ERROR)
  345. {
  346. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  347. {
  348. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  349. if (m_nProxyOpID==PROXYOP_CONNECT)
  350. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  351. else
  352. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  353. Reset();
  354. }
  355. return;
  356. }
  357. m_nRecvBufferPos+=numread;
  358. if (m_nRecvBufferPos==2)
  359. {
  360. if (m_pRecvBuffer[0]!=5)
  361. {
  362. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  363. if (m_nProxyOpID==PROXYOP_CONNECT)
  364. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  365. else
  366. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  367. Reset();
  368. ClearBuffer();
  369. return;
  370. }
  371. if (m_pRecvBuffer[1])
  372. {
  373. //Auth needed
  374. if (m_pRecvBuffer[1]!=2)
  375. {
  376. //Unknown auth type
  377. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
  378. if (m_nProxyOpID==PROXYOP_CONNECT)
  379. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  380. else
  381. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  382. Reset();
  383. ClearBuffer();
  384. return;
  385. }
  386. if (!m_ProxyData.bUseLogon)
  387. {
  388. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
  389. if (m_nProxyOpID==PROXYOP_CONNECT)
  390. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  391. else
  392. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  393. Reset();
  394. ClearBuffer();
  395. return;
  396. }
  397. //Send authentication
  398. LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
  399. LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
  400. ASSERT(strlen(lpszAsciiUser)<=255);
  401. ASSERT(strlen(lpszAsciiPass)<=255);
  402. unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
  403. sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
  404. buffer[0]=1;
  405. buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
  406. buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
  407. int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
  408. int res=SendNext(buffer,len);
  409. delete [] buffer;
  410. if (res==SOCKET_ERROR || res<len)
  411. {
  412. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  413. {
  414. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  415. if (m_nProxyOpID==PROXYOP_CONNECT)
  416. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  417. else
  418. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  419. Reset();
  420. return;
  421. }
  422. }
  423. ClearBuffer();
  424. m_nProxyOpState++;
  425. return;
  426. }
  427. }
  428. //No auth needed
  429. //Send connection request
  430. #ifdef MPEXT
  431. const
  432. #endif
  433. char *lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  434. char *command=new char[10+strlen(lpszAsciiHost)+1];
  435. memset(command,0,10+strlen(lpszAsciiHost)+1);
  436. command[0]=5;
  437. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  438. command[2]=0;
  439. command[3]=m_nProxyPeerIp?1:3;
  440. int len=4;
  441. if (m_nProxyPeerIp)
  442. {
  443. memcpy(&command[len],&m_nProxyPeerIp,4);
  444. len+=4;
  445. }
  446. else
  447. {
  448. command[len]=strlen(lpszAsciiHost);
  449. strcpy(&command[len+1], lpszAsciiHost);
  450. len += strlen(lpszAsciiHost) + 1;
  451. }
  452. memcpy(&command[len], &m_nProxyPeerPort, 2);
  453. len+=2;
  454. int res=SendNext(command,len);
  455. delete [] command;
  456. if (res==SOCKET_ERROR || res<len)
  457. {
  458. if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  459. {
  460. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  461. if (m_nProxyOpID==PROXYOP_CONNECT)
  462. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  463. else
  464. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  465. Reset();
  466. return;
  467. }
  468. }
  469. m_nProxyOpState+=2;
  470. ClearBuffer();
  471. return;
  472. }
  473. else if (m_nProxyOpState==2)
  474. {
  475. //Response to the auth request
  476. if (!m_pRecvBuffer)
  477. m_pRecvBuffer=new char[2];
  478. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
  479. if (numread==SOCKET_ERROR)
  480. {
  481. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  482. {
  483. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  484. if (m_nProxyOpID==PROXYOP_CONNECT)
  485. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  486. else
  487. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  488. Reset();
  489. }
  490. return;
  491. }
  492. m_nRecvBufferPos+=numread;
  493. if (m_nRecvBufferPos==2)
  494. {
  495. if (m_pRecvBuffer[1]!=0)
  496. {
  497. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
  498. if (m_nProxyOpID==PROXYOP_CONNECT)
  499. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  500. else
  501. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  502. Reset();
  503. ClearBuffer();
  504. return;
  505. }
  506. #ifdef MPEXT
  507. const
  508. #endif
  509. char * lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  510. char *command = new char[10+strlen(lpszAsciiHost)+1];
  511. memset(command,0,10+strlen(lpszAsciiHost)+1);
  512. command[0]=5;
  513. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  514. command[2]=0;
  515. command[3]=m_nProxyPeerIp?1:3;
  516. int len=4;
  517. if (m_nProxyPeerIp)
  518. {
  519. memcpy(&command[len],&m_nProxyPeerIp,4);
  520. len+=4;
  521. }
  522. else
  523. {
  524. command[len]=strlen(lpszAsciiHost);
  525. strcpy(&command[len+1],lpszAsciiHost);
  526. len+=strlen(lpszAsciiHost)+1;
  527. }
  528. memcpy(&command[len],&m_nProxyPeerPort,2);
  529. len+=2;
  530. int res=SendNext(command,len);
  531. delete [] command;
  532. if (res==SOCKET_ERROR || res<len)
  533. {
  534. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  535. {
  536. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  537. if (m_nProxyOpID==PROXYOP_CONNECT)
  538. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  539. else
  540. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  541. Reset();
  542. return;
  543. }
  544. }
  545. m_nProxyOpState++;
  546. ClearBuffer();
  547. return;
  548. }
  549. }
  550. else if (m_nProxyOpState==3)
  551. {
  552. //Response to the connection request
  553. if (!m_pRecvBuffer)
  554. {
  555. m_pRecvBuffer=new char[10];
  556. m_nRecvBufferLen=5;
  557. }
  558. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
  559. if (numread==SOCKET_ERROR)
  560. {
  561. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  562. {
  563. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  564. if (m_nProxyOpID==PROXYOP_CONNECT)
  565. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  566. else
  567. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  568. Reset();
  569. }
  570. return;
  571. }
  572. m_nRecvBufferPos+=numread;
  573. if (m_nRecvBufferPos==m_nRecvBufferLen)
  574. {
  575. //Check for errors
  576. if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
  577. {
  578. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  579. if (m_nProxyOpID==PROXYOP_CONNECT)
  580. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  581. else
  582. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  583. Reset();
  584. ClearBuffer();
  585. return;
  586. }
  587. if (m_nRecvBufferLen==5)
  588. {
  589. //Check which kind of address the response contains
  590. if (m_pRecvBuffer[3]==1)
  591. m_nRecvBufferLen=10;
  592. else
  593. {
  594. char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
  595. memcpy(tmp,m_pRecvBuffer,5);
  596. delete [] m_pRecvBuffer;
  597. m_pRecvBuffer=tmp;
  598. m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
  599. }
  600. return;
  601. }
  602. if (m_nProxyOpID==PROXYOP_CONNECT)
  603. {
  604. //OK, we are connected with the remote server
  605. Reset();
  606. ClearBuffer();
  607. TriggerEvent(FD_CONNECT, 0, TRUE);
  608. TriggerEvent(FD_READ, 0, TRUE);
  609. TriggerEvent(FD_WRITE, 0, TRUE);
  610. }
  611. else
  612. {
  613. //Listen socket created
  614. m_nProxyOpState++;
  615. unsigned long ip;
  616. unsigned short port;
  617. ASSERT(m_pRecvBuffer[3]==1);
  618. memcpy(&ip, &m_pRecvBuffer[4], 4);
  619. memcpy(&port, &m_pRecvBuffer[8], 2);
  620. t_ListenSocketCreatedStruct data;
  621. data.ip=ip;
  622. data.nPort=port;
  623. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  624. }
  625. ClearBuffer();
  626. }
  627. }
  628. else if (m_nProxyOpState==4)
  629. {
  630. if (!m_pRecvBuffer)
  631. m_pRecvBuffer=new char[10];
  632. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
  633. if (numread==SOCKET_ERROR)
  634. {
  635. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  636. {
  637. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  638. if (m_nProxyOpID==PROXYOP_CONNECT)
  639. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  640. else
  641. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  642. Reset();
  643. }
  644. return;
  645. }
  646. m_nRecvBufferPos+=numread;
  647. if (m_nRecvBufferPos==10)
  648. {
  649. if (m_pRecvBuffer[1]!=0)
  650. {
  651. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  652. if (m_nProxyOpID==PROXYOP_CONNECT)
  653. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  654. else
  655. {
  656. VERIFY(m_nProxyOpID==PROXYOP_LISTEN);
  657. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  658. }
  659. Reset();
  660. ClearBuffer();
  661. return;
  662. }
  663. //Connection to remote server established
  664. ClearBuffer();
  665. Reset();
  666. TriggerEvent(FD_ACCEPT, 0, TRUE);
  667. TriggerEvent(FD_READ, 0, TRUE);
  668. TriggerEvent(FD_WRITE, 0, TRUE);
  669. }
  670. }
  671. }
  672. if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  673. {
  674. ASSERT (m_nProxyOpID==PROXYOP_CONNECT);
  675. char buffer[9]={0};
  676. for(;;)
  677. {
  678. int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
  679. if (numread==SOCKET_ERROR)
  680. {
  681. int nError=WSAGetLastError();
  682. if (nError!=WSAEWOULDBLOCK)
  683. {
  684. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  685. Reset();
  686. ClearBuffer();
  687. TriggerEvent(FD_CONNECT, nError, TRUE );
  688. }
  689. return;
  690. }
  691. //Response begins with HTTP/
  692. if (!m_pStrBuffer)
  693. {
  694. m_pStrBuffer = new char[strlen(buffer) + 1];
  695. strcpy(m_pStrBuffer, buffer);
  696. }
  697. else
  698. {
  699. char *tmp = m_pStrBuffer;
  700. m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
  701. strcpy(m_pStrBuffer, tmp);
  702. strcpy(m_pStrBuffer + strlen(tmp), buffer);
  703. delete [] tmp;
  704. }
  705. memset(buffer, 0, 9);
  706. const char start[] = "HTTP/";
  707. if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
  708. {
  709. char* str = new char[strlen("No valid HTTP response") + 1];
  710. strcpy(str, "No valid HTTP response");
  711. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, str);
  712. Reset();
  713. ClearBuffer();
  714. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  715. return;
  716. }
  717. char *pos = strstr(m_pStrBuffer, "\r\n");
  718. if (pos)
  719. {
  720. char *pos2 = strstr(m_pStrBuffer, " ");
  721. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  722. {
  723. char *tmp = new char[pos-m_pStrBuffer + 1];
  724. tmp[pos-m_pStrBuffer] = 0;
  725. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  726. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, tmp);
  727. Reset();
  728. ClearBuffer();
  729. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  730. return;
  731. }
  732. }
  733. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  734. {
  735. Reset();
  736. ClearBuffer();
  737. TriggerEvent(FD_CONNECT, 0, TRUE);
  738. TriggerEvent(FD_READ, 0, TRUE);
  739. TriggerEvent(FD_WRITE, 0, TRUE);
  740. return;
  741. }
  742. }
  743. }
  744. }
  745. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  746. {
  747. if (!m_ProxyData.nProxyType)
  748. //Connect normally because there is no proxy
  749. return ConnectNext(lpszHostAddress, nHostPort);
  750. USES_CONVERSION;
  751. //Translate the host address
  752. ASSERT(lpszHostAddress != NULL);
  753. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  754. {
  755. // We can send hostname to proxy, no need to resolve it
  756. //Connect to proxy server
  757. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  758. if (!res)
  759. {
  760. if (WSAGetLastError() != WSAEWOULDBLOCK)
  761. {
  762. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  763. return FALSE;
  764. }
  765. }
  766. m_nProxyPeerPort = htons((u_short)nHostPort);
  767. m_nProxyPeerIp = 0;
  768. delete [] m_pProxyPeerHost;
  769. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  770. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  771. m_nProxyOpID=PROXYOP_CONNECT;
  772. return TRUE;
  773. }
  774. SOCKADDR_IN sockAddr;
  775. memset(&sockAddr,0,sizeof(sockAddr));
  776. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  777. sockAddr.sin_family = AF_INET;
  778. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  779. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  780. {
  781. LPHOSTENT lphost;
  782. lphost = gethostbyname(lpszAscii);
  783. if (lphost != NULL)
  784. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  785. else
  786. {
  787. //Can't resolve hostname
  788. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  789. WSASetLastError(WSAEINVAL);
  790. return FALSE;
  791. }
  792. }
  793. sockAddr.sin_port = htons((u_short)nHostPort);
  794. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  795. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  796. {
  797. delete [] m_pProxyPeerHost;
  798. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  799. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  800. }
  801. return res;
  802. }
  803. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  804. {
  805. if (!m_ProxyData.nProxyType)
  806. {
  807. //Connect normally because there is no proxy
  808. return ConnectNext(lpSockAddr, nSockAddrLen );
  809. }
  810. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  811. //Save server details
  812. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  813. m_nProxyPeerPort=sockAddr->sin_port;
  814. delete [] m_pProxyPeerHost;
  815. m_pProxyPeerHost = NULL;
  816. m_nProxyOpID=PROXYOP_CONNECT;
  817. USES_CONVERSION;
  818. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  819. if (!res)
  820. {
  821. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  822. {
  823. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  824. return FALSE;
  825. }
  826. }
  827. return res;
  828. }
  829. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  830. {
  831. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  832. {
  833. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  834. return;
  835. }
  836. ASSERT(m_nProxyOpID);
  837. if (!m_nProxyOpID)
  838. {
  839. //This should not happen
  840. return;
  841. };
  842. if (nErrorCode)
  843. { //Can't connect to proxy
  844. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  845. if (m_nProxyOpID==PROXYOP_CONNECT)
  846. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  847. else
  848. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  849. Reset();
  850. ClearBuffer();
  851. return;
  852. }
  853. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  854. {
  855. if (m_nProxyOpState)
  856. //Somehow OnConnect has been called more than once
  857. return;
  858. ASSERT(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  859. ClearBuffer();
  860. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOERROR, 0);
  861. //Send the initial request
  862. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  863. { //SOCKS4 proxy
  864. //Send request
  865. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  866. char *command=new char [9+strlen(lpszAscii)+1];
  867. memset(command,0,9+strlen(lpszAscii)+1);
  868. int len=9;
  869. command[0]=4;
  870. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  871. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  872. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  873. {
  874. ASSERT(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  875. ASSERT(strcmp(lpszAscii, ""));
  876. //Set the IP to 0.0.0.x (x is nonzero)
  877. command[4]=0;
  878. command[5]=0;
  879. command[6]=0;
  880. command[7]=1;
  881. //Add host as URL
  882. strcpy(&command[9],lpszAscii);
  883. len+=strlen(lpszAscii)+1;
  884. }
  885. else
  886. memcpy(&command[4],&m_nProxyPeerIp,4);
  887. int res=SendNext(command,len); //Send command
  888. delete [] command;
  889. int nErrorCode=WSAGetLastError();
  890. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  891. {
  892. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  893. if (m_nProxyOpID==PROXYOP_CONNECT)
  894. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  895. else
  896. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  897. Reset();
  898. ClearBuffer();
  899. return;
  900. }
  901. else if (res<len)
  902. {
  903. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  904. if (m_nProxyOpID==PROXYOP_CONNECT)
  905. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  906. else
  907. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  908. Reset();
  909. ClearBuffer();
  910. return;
  911. }
  912. }
  913. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  914. { //SOCKS5 proxy
  915. //Send initialization request
  916. unsigned char command[10];
  917. memset(command,0,10);
  918. command[0]=5;
  919. //CAsyncProxySocketLayer supports to logon types: No logon and
  920. //cleartext username/password (if set) logon
  921. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  922. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  923. int len=m_ProxyData.bUseLogon?4:3; //length of request
  924. int res=SendNext(command,len);
  925. int nErrorCode=WSAGetLastError();
  926. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  927. {
  928. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  929. if (m_nProxyOpID==PROXYOP_CONNECT)
  930. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  931. else
  932. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  933. Reset();
  934. ClearBuffer();
  935. return;
  936. }
  937. else if (res<len)
  938. {
  939. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  940. if (m_nProxyOpID==PROXYOP_CONNECT)
  941. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  942. else
  943. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  944. Reset();
  945. ClearBuffer();
  946. return;
  947. }
  948. }
  949. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  950. {
  951. char str[4096]; //This should be large enough
  952. char * pHost = NULL;
  953. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  954. {
  955. pHost = new char[strlen(m_pProxyPeerHost)+1];
  956. strcpy(pHost, m_pProxyPeerHost);
  957. }
  958. else
  959. {
  960. pHost = new char[16];
  961. sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  962. }
  963. if (!m_ProxyData.bUseLogon)
  964. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  965. pHost, ntohs(m_nProxyPeerPort));
  966. else
  967. {
  968. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  969. pHost, ntohs(m_nProxyPeerPort));
  970. char userpass[4096];
  971. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  972. char base64str[4096];
  973. CBase64Coding base64coding;
  974. if (!base64coding.Encode(userpass, strlen(userpass), base64str))
  975. {
  976. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  977. if (m_nProxyOpID==PROXYOP_CONNECT)
  978. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  979. else
  980. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  981. Reset();
  982. ClearBuffer();
  983. delete [] pHost;
  984. return;
  985. }
  986. strcat(str, "Authorization: Basic ");
  987. strcat(str, base64str);
  988. strcat(str, "\r\nProxy-Authorization: Basic ");
  989. strcat(str, base64str);
  990. strcat(str, "\r\n\r\n");
  991. }
  992. delete [] pHost;
  993. USES_CONVERSION;
  994. int numsent=SendNext(str, strlen(str) );
  995. int nErrorCode=WSAGetLastError();
  996. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  997. {
  998. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  999. if (m_nProxyOpID==PROXYOP_CONNECT)
  1000. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  1001. else
  1002. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  1003. Reset();
  1004. ClearBuffer();
  1005. return;
  1006. }
  1007. else if ( numsent < static_cast<int>( strlen(str) ) )
  1008. {
  1009. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  1010. if (m_nProxyOpID==PROXYOP_CONNECT)
  1011. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  1012. else
  1013. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  1014. Reset();
  1015. ClearBuffer();
  1016. return;
  1017. }
  1018. m_nProxyOpState++;
  1019. return;
  1020. }
  1021. else
  1022. ASSERT(FALSE);
  1023. //Now we'll wait for the response, handled in OnReceive
  1024. m_nProxyOpState++;
  1025. }
  1026. }
  1027. void CAsyncProxySocketLayer::ClearBuffer()
  1028. {
  1029. delete [] m_pStrBuffer;
  1030. m_pStrBuffer = NULL;
  1031. if (m_pRecvBuffer)
  1032. {
  1033. delete [] m_pRecvBuffer;
  1034. m_pRecvBuffer=0;
  1035. }
  1036. m_nRecvBufferLen=0;
  1037. m_nRecvBufferPos=0;
  1038. }
  1039. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  1040. {
  1041. if (GetProxyType()==PROXYTYPE_NOPROXY)
  1042. return ListenNext(nConnectionBacklog);
  1043. USES_CONVERSION;
  1044. //Connect to proxy server
  1045. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  1046. if (!res)
  1047. {
  1048. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  1049. {
  1050. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  1051. return FALSE;
  1052. }
  1053. }
  1054. m_nProxyPeerPort=0;
  1055. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  1056. m_nProxyOpID=PROXYOP_LISTEN;
  1057. return TRUE;
  1058. }
  1059. #ifdef _AFX
  1060. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  1061. {
  1062. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1063. {
  1064. return GetPeerNameNext(rPeerAddress, rPeerPort);
  1065. }
  1066. if (GetLayerState()==notsock)
  1067. {
  1068. WSASetLastError(WSAENOTSOCK);
  1069. return FALSE;
  1070. }
  1071. else if (GetLayerState()!=connected)
  1072. {
  1073. WSASetLastError(WSAENOTCONN);
  1074. return FALSE;
  1075. }
  1076. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1077. {
  1078. WSASetLastError(WSAENOTCONN);
  1079. return FALSE;
  1080. }
  1081. ASSERT(m_ProxyData.nProxyType);
  1082. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  1083. if (res)
  1084. {
  1085. rPeerPort=ntohs(m_nProxyPeerPort);
  1086. rPeerAddress.Format(_T("%d.%d.%d.%d"), m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  1087. }
  1088. return res;
  1089. }
  1090. #endif
  1091. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1092. {
  1093. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1094. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  1095. if (GetLayerState()==notsock)
  1096. {
  1097. WSASetLastError(WSAENOTSOCK);
  1098. return FALSE;
  1099. }
  1100. else if (GetLayerState()!=connected)
  1101. {
  1102. WSASetLastError(WSAENOTCONN);
  1103. return FALSE;
  1104. }
  1105. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1106. {
  1107. WSASetLastError(WSAENOTCONN);
  1108. return FALSE;
  1109. }
  1110. ASSERT(m_ProxyData.nProxyType);
  1111. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  1112. if (res)
  1113. {
  1114. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  1115. addr->sin_port=m_nProxyPeerPort;
  1116. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  1117. }
  1118. return res;
  1119. }
  1120. int CAsyncProxySocketLayer::GetProxyType() const
  1121. {
  1122. return m_ProxyData.nProxyType;
  1123. }
  1124. void CAsyncProxySocketLayer::Close()
  1125. {
  1126. delete [] m_ProxyData.pProxyHost;
  1127. delete [] m_ProxyData.pProxyUser;
  1128. delete [] m_ProxyData.pProxyPass;
  1129. delete [] m_pProxyPeerHost;
  1130. m_ProxyData.pProxyHost = NULL;
  1131. m_ProxyData.pProxyUser = NULL;
  1132. m_ProxyData.pProxyPass = NULL;
  1133. m_pProxyPeerHost = NULL;
  1134. ClearBuffer();
  1135. Reset();
  1136. CloseNext();
  1137. }
  1138. void CAsyncProxySocketLayer::Reset()
  1139. {
  1140. m_nProxyOpState=0;
  1141. m_nProxyOpID=0;
  1142. }
  1143. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  1144. {
  1145. if (m_nProxyOpID)
  1146. {
  1147. WSASetLastError(WSAEWOULDBLOCK);
  1148. return SOCKET_ERROR;
  1149. }
  1150. return SendNext(lpBuf, nBufLen, nFlags);
  1151. }
  1152. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  1153. {
  1154. if (m_nProxyOpID)
  1155. {
  1156. WSASetLastError(WSAEWOULDBLOCK);
  1157. return SOCKET_ERROR;
  1158. }
  1159. return ReceiveNext(lpBuf, nBufLen, nFlags);
  1160. }
  1161. BOOL CAsyncProxySocketLayer::PrepareListen(unsigned long ip)
  1162. {
  1163. if (GetLayerState()!=notsock && GetLayerState()!=unconnected)
  1164. return FALSE;
  1165. m_nProxyPeerIp=ip;
  1166. return TRUE;
  1167. }
  1168. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1169. {
  1170. if (!m_ProxyData.nProxyType)
  1171. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1172. GetPeerName(lpSockAddr, lpSockAddrLen);
  1173. return TRUE;
  1174. }