AsyncProxySocketLayer.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244
  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. //Validate the parameters
  145. ASSERT(nProxyType==PROXYTYPE_SOCKS4 ||
  146. nProxyType==PROXYTYPE_SOCKS4A ||
  147. nProxyType==PROXYTYPE_SOCKS5 ||
  148. nProxyType==PROXYTYPE_HTTP11);
  149. ASSERT(!m_nProxyOpID);
  150. ASSERT(pProxyHost && *pProxyHost);
  151. ASSERT(ProxyPort>0);
  152. ASSERT(ProxyPort<=65535);
  153. delete m_ProxyData.pProxyHost;
  154. delete m_ProxyData.pProxyUser;
  155. delete m_ProxyData.pProxyPass;
  156. m_ProxyData.pProxyUser = NULL;
  157. m_ProxyData.pProxyPass = NULL;
  158. m_ProxyData.nProxyType = nProxyType;
  159. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  160. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  161. m_ProxyData.nProxyPort = ProxyPort;
  162. m_ProxyData.bUseLogon = FALSE;
  163. }
  164. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, const char * pProxyUser, const char * pProxyPass)
  165. {
  166. //Validate the parameters
  167. ASSERT(nProxyType==PROXYTYPE_SOCKS5 || nProxyType==PROXYTYPE_HTTP11);
  168. ASSERT(!m_nProxyOpID);
  169. ASSERT(pProxyHost && *pProxyHost);
  170. ASSERT(ProxyPort>0);
  171. ASSERT(ProxyPort<=65535);
  172. delete m_ProxyData.pProxyHost;
  173. delete m_ProxyData.pProxyUser;
  174. delete m_ProxyData.pProxyPass;
  175. m_ProxyData.pProxyUser = NULL;
  176. m_ProxyData.pProxyPass = NULL;
  177. m_ProxyData.nProxyType = nProxyType;
  178. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  179. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  180. m_ProxyData.nProxyPort=ProxyPort;
  181. if (pProxyUser)
  182. {
  183. m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
  184. strcpy(m_ProxyData.pProxyUser, pProxyUser);
  185. }
  186. if (pProxyPass)
  187. {
  188. m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
  189. strcpy(m_ProxyData.pProxyPass, pProxyPass);
  190. }
  191. m_ProxyData.bUseLogon = TRUE;
  192. }
  193. void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
  194. {
  195. //Here we handle the responses from the SOCKS proxy
  196. if (!m_nProxyOpID)
  197. {
  198. TriggerEvent(FD_READ, nErrorCode, TRUE);
  199. return;
  200. }
  201. if (nErrorCode)
  202. {
  203. TriggerEvent(FD_READ, nErrorCode, TRUE);
  204. }
  205. if (!m_nProxyOpState) //We should not receive a response yet!
  206. { //Ignore it
  207. return;
  208. }
  209. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  210. {
  211. if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
  212. {
  213. if (!m_pRecvBuffer)
  214. m_pRecvBuffer=new char[8];
  215. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-m_nRecvBufferPos);
  216. if (numread==SOCKET_ERROR)
  217. {
  218. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  219. {
  220. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  221. if (m_nProxyOpID==PROXYOP_CONNECT)
  222. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  223. else
  224. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  225. Reset();
  226. ClearBuffer();
  227. }
  228. return;
  229. }
  230. m_nRecvBufferPos+=numread;
  231. if (m_nRecvBufferPos==8)
  232. {
  233. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  234. {
  235. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  236. if (m_nProxyOpID==PROXYOP_CONNECT)
  237. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  238. else
  239. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  240. Reset();
  241. ClearBuffer();
  242. return;
  243. }
  244. if (m_nProxyOpID==PROXYOP_CONNECT)
  245. {
  246. //OK, we are connected with the remote server
  247. ClearBuffer();
  248. Reset();
  249. TriggerEvent(FD_CONNECT, 0, TRUE);
  250. TriggerEvent(FD_READ, 0, TRUE);
  251. TriggerEvent(FD_WRITE, 0, TRUE);
  252. return;
  253. }
  254. else
  255. {
  256. //Listen socket created
  257. m_nProxyOpState++;
  258. unsigned long ip;
  259. int port;
  260. memcpy(&ip,&m_pRecvBuffer[4],4);
  261. if (!ip)
  262. { //No IP return, use the IP of the proxy server
  263. SOCKADDR SockAddr;
  264. memset(&SockAddr,0,sizeof(SockAddr));
  265. int SockAddrLen=sizeof(SockAddr);
  266. if (GetPeerName(&SockAddr, &SockAddrLen ))
  267. {
  268. ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
  269. }
  270. else
  271. {
  272. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  273. if (m_nProxyOpID==PROXYOP_CONNECT)
  274. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  275. else
  276. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  277. Reset();
  278. ClearBuffer();
  279. return;
  280. }
  281. }
  282. memcpy(&port,&m_pRecvBuffer[2],2);
  283. t_ListenSocketCreatedStruct data;
  284. data.ip=ip;
  285. data.nPort=port;
  286. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  287. }
  288. ClearBuffer();
  289. }
  290. }
  291. else if (m_nProxyOpID==2)
  292. {
  293. if (!m_pRecvBuffer)
  294. m_pRecvBuffer=new char[8];
  295. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-m_nRecvBufferPos);
  296. if (numread==SOCKET_ERROR)
  297. {
  298. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  299. {
  300. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  301. if (m_nProxyOpID==PROXYOP_CONNECT)
  302. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  303. else
  304. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  305. Reset();
  306. ClearBuffer();
  307. }
  308. return;
  309. }
  310. m_nRecvBufferPos+=numread;
  311. if (m_nRecvBufferPos==8)
  312. {
  313. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  314. {
  315. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  316. if (m_nProxyOpID==PROXYOP_CONNECT)
  317. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  318. else
  319. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  320. Reset();
  321. ClearBuffer();
  322. return;
  323. }
  324. //Connection to remote server established
  325. ClearBuffer();
  326. Reset();
  327. TriggerEvent(FD_ACCEPT, 0, TRUE);
  328. TriggerEvent(FD_READ, 0, TRUE);
  329. TriggerEvent(FD_WRITE, 0, TRUE);
  330. }
  331. }
  332. }
  333. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  334. {
  335. if (m_nProxyOpState==1) //Get respone to initialization message
  336. {
  337. if (!m_pRecvBuffer)
  338. m_pRecvBuffer=new char[2];
  339. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,2-m_nRecvBufferPos);
  340. if (numread==SOCKET_ERROR)
  341. {
  342. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  343. {
  344. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  345. if (m_nProxyOpID==PROXYOP_CONNECT)
  346. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  347. else
  348. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  349. Reset();
  350. }
  351. return;
  352. }
  353. m_nRecvBufferPos+=numread;
  354. if (m_nRecvBufferPos==2)
  355. {
  356. if (m_pRecvBuffer[0]!=5)
  357. {
  358. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  359. if (m_nProxyOpID==PROXYOP_CONNECT)
  360. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  361. else
  362. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  363. Reset();
  364. ClearBuffer();
  365. return;
  366. }
  367. if (m_pRecvBuffer[1])
  368. { //Auth needed
  369. if (m_pRecvBuffer[1]!=2)
  370. { //Unknown auth type
  371. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
  372. if (m_nProxyOpID==PROXYOP_CONNECT)
  373. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  374. else
  375. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  376. Reset();
  377. ClearBuffer();
  378. return;
  379. }
  380. if (!m_ProxyData.bUseLogon)
  381. {
  382. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
  383. if (m_nProxyOpID==PROXYOP_CONNECT)
  384. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  385. else
  386. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  387. Reset();
  388. ClearBuffer();
  389. return;
  390. }
  391. //Send authentication
  392. LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
  393. LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
  394. ASSERT(strlen(lpszAsciiUser)<=255);
  395. ASSERT(strlen(lpszAsciiPass)<=255);
  396. unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
  397. sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
  398. buffer[0]=1;
  399. buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
  400. buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
  401. int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
  402. int res=SendNext(buffer,len);
  403. delete [] buffer;
  404. if (res==SOCKET_ERROR || res<len)
  405. {
  406. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  407. {
  408. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  409. if (m_nProxyOpID==PROXYOP_CONNECT)
  410. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  411. else
  412. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  413. Reset();
  414. return;
  415. }
  416. }
  417. ClearBuffer();
  418. m_nProxyOpState++;
  419. return;
  420. }
  421. }
  422. //No auth needed
  423. //Send connection request
  424. #ifdef MPEXT
  425. const
  426. #endif
  427. char *lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  428. char *command=new char[10+strlen(lpszAsciiHost)+1];
  429. memset(command,0,10+strlen(lpszAsciiHost)+1);
  430. command[0]=5;
  431. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  432. command[2]=0;
  433. command[3]=m_nProxyPeerIp?1:3;
  434. int len=4;
  435. if (m_nProxyPeerIp)
  436. {
  437. memcpy(&command[len],&m_nProxyPeerIp,4);
  438. len+=4;
  439. }
  440. else
  441. {
  442. command[len]=strlen(lpszAsciiHost);
  443. strcpy(&command[len+1], lpszAsciiHost);
  444. len += strlen(lpszAsciiHost) + 1;
  445. }
  446. memcpy(&command[len], &m_nProxyPeerPort, 2);
  447. len+=2;
  448. int res=SendNext(command,len);
  449. delete [] command;
  450. if (res==SOCKET_ERROR || res<len)
  451. {
  452. if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  453. {
  454. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  455. if (m_nProxyOpID==PROXYOP_CONNECT)
  456. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  457. else
  458. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  459. Reset();
  460. return;
  461. }
  462. }
  463. m_nProxyOpState+=2;
  464. ClearBuffer();
  465. return;
  466. }
  467. else if (m_nProxyOpState==2)
  468. {//Response to the auth request
  469. if (!m_pRecvBuffer)
  470. m_pRecvBuffer=new char[2];
  471. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
  472. if (numread==SOCKET_ERROR)
  473. {
  474. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  475. {
  476. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  477. if (m_nProxyOpID==PROXYOP_CONNECT)
  478. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  479. else
  480. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  481. Reset();
  482. }
  483. return;
  484. }
  485. m_nRecvBufferPos+=numread;
  486. if (m_nRecvBufferPos==2)
  487. {
  488. if (m_pRecvBuffer[1]!=0)
  489. {
  490. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
  491. if (m_nProxyOpID==PROXYOP_CONNECT)
  492. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  493. else
  494. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  495. Reset();
  496. ClearBuffer();
  497. return;
  498. }
  499. #ifdef MPEXT
  500. const
  501. #endif
  502. char * lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  503. char *command = new char[10+strlen(lpszAsciiHost)+1];
  504. memset(command,0,10+strlen(lpszAsciiHost)+1);
  505. command[0]=5;
  506. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  507. command[2]=0;
  508. command[3]=m_nProxyPeerIp?1:3;
  509. int len=4;
  510. if (m_nProxyPeerIp)
  511. {
  512. memcpy(&command[len],&m_nProxyPeerIp,4);
  513. len+=4;
  514. }
  515. else
  516. {
  517. command[len]=strlen(lpszAsciiHost);
  518. strcpy(&command[len+1],lpszAsciiHost);
  519. len+=strlen(lpszAsciiHost)+1;
  520. }
  521. memcpy(&command[len],&m_nProxyPeerPort,2);
  522. len+=2;
  523. int res=SendNext(command,len);
  524. delete [] command;
  525. if (res==SOCKET_ERROR || res<len)
  526. {
  527. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  528. {
  529. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  530. if (m_nProxyOpID==PROXYOP_CONNECT)
  531. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  532. else
  533. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  534. Reset();
  535. return;
  536. }
  537. }
  538. m_nProxyOpState++;
  539. ClearBuffer();
  540. return;
  541. }
  542. }
  543. else if (m_nProxyOpState==3)
  544. {//Response to the connection request
  545. if (!m_pRecvBuffer)
  546. {
  547. m_pRecvBuffer=new char[10];
  548. m_nRecvBufferLen=5;
  549. }
  550. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
  551. if (numread==SOCKET_ERROR)
  552. {
  553. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  554. {
  555. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  556. if (m_nProxyOpID==PROXYOP_CONNECT)
  557. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  558. else
  559. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  560. Reset();
  561. }
  562. return;
  563. }
  564. m_nRecvBufferPos+=numread;
  565. if (m_nRecvBufferPos==m_nRecvBufferLen)
  566. {
  567. //Check for errors
  568. if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
  569. {
  570. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  571. if (m_nProxyOpID==PROXYOP_CONNECT)
  572. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  573. else
  574. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  575. Reset();
  576. ClearBuffer();
  577. return;
  578. }
  579. if (m_nRecvBufferLen==5)
  580. { //Check which kind of address the response contains
  581. if (m_pRecvBuffer[3]==1)
  582. m_nRecvBufferLen=10;
  583. else
  584. {
  585. char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
  586. memcpy(tmp,m_pRecvBuffer,5);
  587. delete [] m_pRecvBuffer;
  588. m_pRecvBuffer=tmp;
  589. m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
  590. }
  591. return;
  592. }
  593. if (m_nProxyOpID==PROXYOP_CONNECT)
  594. {
  595. //OK, we are connected with the remote server
  596. Reset();
  597. ClearBuffer();
  598. TriggerEvent(FD_CONNECT, 0, TRUE);
  599. TriggerEvent(FD_READ, 0, TRUE);
  600. TriggerEvent(FD_WRITE, 0, TRUE);
  601. }
  602. else
  603. {
  604. //Listen socket created
  605. m_nProxyOpState++;
  606. unsigned long ip;
  607. unsigned short port;
  608. ASSERT(m_pRecvBuffer[3]==1);
  609. memcpy(&ip, &m_pRecvBuffer[4], 4);
  610. memcpy(&port, &m_pRecvBuffer[8], 2);
  611. t_ListenSocketCreatedStruct data;
  612. data.ip=ip;
  613. data.nPort=port;
  614. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  615. }
  616. ClearBuffer();
  617. }
  618. }
  619. else if (m_nProxyOpState==4)
  620. {
  621. if (!m_pRecvBuffer)
  622. m_pRecvBuffer=new char[10];
  623. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
  624. if (numread==SOCKET_ERROR)
  625. {
  626. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  627. {
  628. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  629. if (m_nProxyOpID==PROXYOP_CONNECT)
  630. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  631. else
  632. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  633. Reset();
  634. }
  635. return;
  636. }
  637. m_nRecvBufferPos+=numread;
  638. if (m_nRecvBufferPos==10)
  639. {
  640. if (m_pRecvBuffer[1]!=0)
  641. {
  642. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  643. if (m_nProxyOpID==PROXYOP_CONNECT)
  644. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  645. else
  646. {
  647. VERIFY(m_nProxyOpID==PROXYOP_LISTEN);
  648. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  649. }
  650. Reset();
  651. ClearBuffer();
  652. return;
  653. }
  654. //Connection to remote server established
  655. ClearBuffer();
  656. Reset();
  657. TriggerEvent(FD_ACCEPT, 0, TRUE);
  658. TriggerEvent(FD_READ, 0, TRUE);
  659. TriggerEvent(FD_WRITE, 0, TRUE);
  660. }
  661. }
  662. }
  663. if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  664. {
  665. ASSERT (m_nProxyOpID==PROXYOP_CONNECT);
  666. char buffer[9]={0};
  667. for(;;)
  668. {
  669. int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
  670. if (numread==SOCKET_ERROR)
  671. {
  672. int nError=WSAGetLastError();
  673. if (nError!=WSAEWOULDBLOCK)
  674. {
  675. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  676. Reset();
  677. ClearBuffer();
  678. TriggerEvent(FD_CONNECT, nError, TRUE );
  679. }
  680. return;
  681. }
  682. //Response begins with HTTP/
  683. if (!m_pStrBuffer)
  684. {
  685. m_pStrBuffer = new char[strlen(buffer) + 1];
  686. strcpy(m_pStrBuffer, buffer);
  687. }
  688. else
  689. {
  690. char *tmp = m_pStrBuffer;
  691. m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
  692. strcpy(m_pStrBuffer, tmp);
  693. strcpy(m_pStrBuffer + strlen(tmp), buffer);
  694. delete [] tmp;
  695. }
  696. memset(buffer, 0, 9);
  697. const char start[] = "HTTP/";
  698. if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
  699. {
  700. char* str = new char[strlen("No valid HTTP response") + 1];
  701. strcpy(str, "No valid HTTP response");
  702. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, str);
  703. Reset();
  704. ClearBuffer();
  705. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  706. return;
  707. }
  708. char *pos = strstr(m_pStrBuffer, "\r\n");
  709. if (pos)
  710. {
  711. char *pos2 = strstr(m_pStrBuffer, " ");
  712. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  713. {
  714. char *tmp = new char[pos-m_pStrBuffer + 1];
  715. tmp[pos-m_pStrBuffer] = 0;
  716. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  717. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, tmp);
  718. Reset();
  719. ClearBuffer();
  720. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  721. return;
  722. }
  723. }
  724. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  725. {
  726. Reset();
  727. ClearBuffer();
  728. TriggerEvent(FD_CONNECT, 0, TRUE);
  729. TriggerEvent(FD_READ, 0, TRUE);
  730. TriggerEvent(FD_WRITE, 0, TRUE);
  731. return;
  732. }
  733. }
  734. }
  735. }
  736. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  737. {
  738. if (!m_ProxyData.nProxyType)
  739. //Connect normally because there is no proxy
  740. return ConnectNext(lpszHostAddress, nHostPort);
  741. USES_CONVERSION;
  742. //Translate the host address
  743. ASSERT(lpszHostAddress != NULL);
  744. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  745. {
  746. // We can send hostname to proxy, no need to resolve it
  747. //Connect to proxy server
  748. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  749. if (!res)
  750. {
  751. if (WSAGetLastError() != WSAEWOULDBLOCK)
  752. {
  753. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  754. return FALSE;
  755. }
  756. }
  757. m_nProxyPeerPort = htons((u_short)nHostPort);
  758. m_nProxyPeerIp = 0;
  759. delete [] m_pProxyPeerHost;
  760. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  761. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  762. m_nProxyOpID=PROXYOP_CONNECT;
  763. return TRUE;
  764. }
  765. SOCKADDR_IN sockAddr;
  766. memset(&sockAddr,0,sizeof(sockAddr));
  767. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  768. sockAddr.sin_family = AF_INET;
  769. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  770. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  771. {
  772. LPHOSTENT lphost;
  773. lphost = gethostbyname(lpszAscii);
  774. if (lphost != NULL)
  775. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  776. else
  777. {
  778. //Can't resolve hostname
  779. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  780. WSASetLastError(WSAEINVAL);
  781. return FALSE;
  782. }
  783. }
  784. sockAddr.sin_port = htons((u_short)nHostPort);
  785. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  786. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  787. {
  788. delete [] m_pProxyPeerHost;
  789. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  790. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  791. }
  792. return res;
  793. }
  794. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  795. {
  796. if (!m_ProxyData.nProxyType)
  797. //Connect normally because there is no proxy
  798. return ConnectNext(lpSockAddr, nSockAddrLen );
  799. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  800. //Save server details
  801. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  802. m_nProxyPeerPort=sockAddr->sin_port;
  803. delete [] m_pProxyPeerHost;
  804. m_pProxyPeerHost = NULL;
  805. m_nProxyOpID=PROXYOP_CONNECT;
  806. USES_CONVERSION;
  807. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  808. if (!res)
  809. {
  810. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  811. {
  812. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  813. return FALSE;
  814. }
  815. }
  816. return res;
  817. }
  818. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  819. {
  820. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  821. {
  822. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  823. return;
  824. }
  825. ASSERT(m_nProxyOpID);
  826. if (!m_nProxyOpID)
  827. {
  828. //This should not happen
  829. return;
  830. };
  831. if (nErrorCode)
  832. { //Can't connect to proxy
  833. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  834. if (m_nProxyOpID==PROXYOP_CONNECT)
  835. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  836. else
  837. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  838. Reset();
  839. ClearBuffer();
  840. return;
  841. }
  842. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  843. {
  844. if (m_nProxyOpState)
  845. //Somehow OnConnect has been called more than once
  846. return;
  847. ASSERT(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  848. ClearBuffer();
  849. //Send the initial request
  850. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  851. { //SOCKS4 proxy
  852. //Send request
  853. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  854. char *command=new char [9+strlen(lpszAscii)+1];
  855. memset(command,0,9+strlen(lpszAscii)+1);
  856. int len=9;
  857. command[0]=4;
  858. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  859. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  860. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  861. {
  862. ASSERT(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  863. ASSERT(strcmp(lpszAscii, ""));
  864. //Set the IP to 0.0.0.x (x is nonzero)
  865. command[4]=0;
  866. command[5]=0;
  867. command[6]=0;
  868. command[7]=1;
  869. //Add host as URL
  870. strcpy(&command[9],lpszAscii);
  871. len+=strlen(lpszAscii)+1;
  872. }
  873. else
  874. memcpy(&command[4],&m_nProxyPeerIp,4);
  875. int res=SendNext(command,len); //Send command
  876. delete [] command;
  877. int nErrorCode=WSAGetLastError();
  878. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  879. {
  880. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  881. if (m_nProxyOpID==PROXYOP_CONNECT)
  882. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  883. else
  884. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  885. Reset();
  886. ClearBuffer();
  887. return;
  888. }
  889. else if (res<len)
  890. {
  891. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  892. if (m_nProxyOpID==PROXYOP_CONNECT)
  893. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  894. else
  895. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  896. Reset();
  897. ClearBuffer();
  898. return;
  899. }
  900. }
  901. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  902. { //SOCKS5 proxy
  903. //Send initialization request
  904. unsigned char command[10];
  905. memset(command,0,10);
  906. command[0]=5;
  907. //CAsyncProxySocketLayer supports to logon types: No logon and
  908. //cleartext username/password (if set) logon
  909. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  910. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  911. int len=m_ProxyData.bUseLogon?4:3; //length of request
  912. int res=SendNext(command,len);
  913. int nErrorCode=WSAGetLastError();
  914. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  915. {
  916. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  917. if (m_nProxyOpID==PROXYOP_CONNECT)
  918. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  919. else
  920. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  921. Reset();
  922. ClearBuffer();
  923. return;
  924. }
  925. else if (res<len)
  926. {
  927. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  928. if (m_nProxyOpID==PROXYOP_CONNECT)
  929. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  930. else
  931. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  932. Reset();
  933. ClearBuffer();
  934. return;
  935. }
  936. }
  937. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  938. {
  939. char str[4096]; //This should be large enough
  940. char * pHost = NULL;
  941. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  942. {
  943. pHost = new char[strlen(m_pProxyPeerHost)+1];
  944. strcpy(pHost, m_pProxyPeerHost);
  945. }
  946. else
  947. {
  948. pHost = new char[16];
  949. sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  950. }
  951. if (!m_ProxyData.bUseLogon)
  952. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  953. pHost, ntohs(m_nProxyPeerPort));
  954. else
  955. {
  956. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  957. pHost, ntohs(m_nProxyPeerPort));
  958. char userpass[4096];
  959. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  960. char base64str[4096];
  961. CBase64Coding base64coding;
  962. if (!base64coding.Encode(userpass, strlen(userpass), base64str))
  963. {
  964. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  965. if (m_nProxyOpID==PROXYOP_CONNECT)
  966. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  967. else
  968. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  969. Reset();
  970. ClearBuffer();
  971. delete [] pHost;
  972. return;
  973. }
  974. strcat(str, "Authorization: Basic ");
  975. strcat(str, base64str);
  976. strcat(str, "\r\nProxy-Authorization: Basic ");
  977. strcat(str, base64str);
  978. strcat(str, "\r\n\r\n");
  979. }
  980. delete [] pHost;
  981. int numsent=SendNext(str, strlen(str) );
  982. int nErrorCode=WSAGetLastError();
  983. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  984. {
  985. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  986. if (m_nProxyOpID==PROXYOP_CONNECT)
  987. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  988. else
  989. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  990. Reset();
  991. ClearBuffer();
  992. return;
  993. }
  994. else if ( numsent < static_cast<int>( strlen(str) ) )
  995. {
  996. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  997. if (m_nProxyOpID==PROXYOP_CONNECT)
  998. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  999. else
  1000. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  1001. Reset();
  1002. ClearBuffer();
  1003. return;
  1004. }
  1005. m_nProxyOpState++;
  1006. return;
  1007. }
  1008. else
  1009. ASSERT(FALSE);
  1010. //Now we'll wait for the response, handled in OnReceive
  1011. m_nProxyOpState++;
  1012. }
  1013. }
  1014. void CAsyncProxySocketLayer::ClearBuffer()
  1015. {
  1016. delete [] m_pStrBuffer;
  1017. m_pStrBuffer = NULL;
  1018. if (m_pRecvBuffer)
  1019. {
  1020. delete [] m_pRecvBuffer;
  1021. m_pRecvBuffer=0;
  1022. }
  1023. m_nRecvBufferLen=0;
  1024. m_nRecvBufferPos=0;
  1025. }
  1026. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  1027. {
  1028. if (GetProxyType()==PROXYTYPE_NOPROXY)
  1029. return ListenNext(nConnectionBacklog);
  1030. USES_CONVERSION;
  1031. //Connect to proxy server
  1032. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  1033. if (!res)
  1034. {
  1035. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  1036. {
  1037. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  1038. return FALSE;
  1039. }
  1040. }
  1041. m_nProxyPeerPort=0;
  1042. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  1043. m_nProxyOpID=PROXYOP_LISTEN;
  1044. return TRUE;
  1045. }
  1046. #ifdef _AFX
  1047. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  1048. {
  1049. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1050. {
  1051. return GetPeerNameNext(rPeerAddress, rPeerPort);
  1052. }
  1053. if (GetLayerState()==notsock)
  1054. {
  1055. WSASetLastError(WSAENOTSOCK);
  1056. return FALSE;
  1057. }
  1058. else if (GetLayerState()!=connected)
  1059. {
  1060. WSASetLastError(WSAENOTCONN);
  1061. return FALSE;
  1062. }
  1063. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1064. {
  1065. WSASetLastError(WSAENOTCONN);
  1066. return FALSE;
  1067. }
  1068. ASSERT(m_ProxyData.nProxyType);
  1069. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  1070. if (res)
  1071. {
  1072. rPeerPort=ntohs(m_nProxyPeerPort);
  1073. rPeerAddress.Format(_T("%d.%d.%d.%d"), m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  1074. }
  1075. return res;
  1076. }
  1077. #endif
  1078. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1079. {
  1080. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1081. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  1082. if (GetLayerState()==notsock)
  1083. {
  1084. WSASetLastError(WSAENOTSOCK);
  1085. return FALSE;
  1086. }
  1087. else if (GetLayerState()!=connected)
  1088. {
  1089. WSASetLastError(WSAENOTCONN);
  1090. return FALSE;
  1091. }
  1092. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1093. {
  1094. WSASetLastError(WSAENOTCONN);
  1095. return FALSE;
  1096. }
  1097. ASSERT(m_ProxyData.nProxyType);
  1098. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  1099. if (res)
  1100. {
  1101. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  1102. addr->sin_port=m_nProxyPeerPort;
  1103. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  1104. }
  1105. return res;
  1106. }
  1107. int CAsyncProxySocketLayer::GetProxyType() const
  1108. {
  1109. return m_ProxyData.nProxyType;
  1110. }
  1111. void CAsyncProxySocketLayer::Close()
  1112. {
  1113. delete [] m_ProxyData.pProxyHost;
  1114. delete [] m_ProxyData.pProxyUser;
  1115. delete [] m_ProxyData.pProxyPass;
  1116. delete [] m_pProxyPeerHost;
  1117. m_ProxyData.pProxyHost = NULL;
  1118. m_ProxyData.pProxyUser = NULL;
  1119. m_ProxyData.pProxyPass = NULL;
  1120. m_pProxyPeerHost = NULL;
  1121. ClearBuffer();
  1122. Reset();
  1123. CloseNext();
  1124. }
  1125. void CAsyncProxySocketLayer::Reset()
  1126. {
  1127. m_nProxyOpState=0;
  1128. m_nProxyOpID=0;
  1129. }
  1130. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  1131. {
  1132. if (m_nProxyOpID)
  1133. {
  1134. WSASetLastError(WSAEWOULDBLOCK);
  1135. return SOCKET_ERROR;
  1136. }
  1137. return SendNext(lpBuf, nBufLen, nFlags);
  1138. }
  1139. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  1140. {
  1141. if (m_nProxyOpID)
  1142. {
  1143. WSASetLastError(WSAEWOULDBLOCK);
  1144. return SOCKET_ERROR;
  1145. }
  1146. return ReceiveNext(lpBuf, nBufLen, nFlags);
  1147. }
  1148. BOOL CAsyncProxySocketLayer::PrepareListen(unsigned long ip)
  1149. {
  1150. if (GetLayerState()!=notsock && GetLayerState()!=unconnected)
  1151. return FALSE;
  1152. m_nProxyPeerIp=ip;
  1153. return TRUE;
  1154. }
  1155. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1156. {
  1157. if (!m_ProxyData.nProxyType)
  1158. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1159. GetPeerName(lpSockAddr, lpSockAddrLen);
  1160. return TRUE;
  1161. }