Advertisement
Guest User

agsxmpp socks5 and HTTP connect proxy patch

a guest
Aug 16th, 2011
1,155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 34.43 KB | None | 0 0
  1. Index: agsXMPP2010.csproj
  2. ===================================================================
  3. --- agsXMPP2010.csproj  (revision 129)
  4. +++ agsXMPP2010.csproj  (working copy)
  5. @@ -12,7 +12,8 @@
  6.      <AssemblyKeyContainerName>
  7.      </AssemblyKeyContainerName>
  8.      <AssemblyName>agsXMPP</AssemblyName>
  9. -    <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
  10. +    <AssemblyOriginatorKeyFile>
  11. +    </AssemblyOriginatorKeyFile>
  12.      <DefaultClientScript>JScript</DefaultClientScript>
  13.      <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
  14.      <DefaultTargetSchema>IE50</DefaultTargetSchema>
  15. @@ -122,6 +123,8 @@
  16.      <Compile Include="Idn\Stringprep.cs" />
  17.      <Compile Include="Idn\StringprepException.cs" />
  18.      <Compile Include="Net\BoshClientSocket.cs" />
  19. +    <Compile Include="Net\ConnectClientSocket.cs" />
  20. +    <Compile Include="Net\Socks5Socket.cs" />
  21.      <Compile Include="Properties\AssemblyInfo.cs">
  22.        <SubType>Code</SubType>
  23.      </Compile>
  24. @@ -734,12 +737,8 @@
  25.      <Compile Include="XmppConnection.cs">
  26.        <SubType>Code</SubType>
  27.      </Compile>
  28. -    <Content Include="changelog.txt" />
  29.    </ItemGroup>
  30.    <ItemGroup>
  31. -    <None Include="key.snk" />
  32. -  </ItemGroup>
  33. -  <ItemGroup>
  34.      <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
  35.        <Visible>False</Visible>
  36.        <ProductName>.NET Framework Client Profile</ProductName>
  37. Index: agsXMPP2010.sln
  38. ===================================================================
  39. --- agsXMPP2010.sln (revision 0)
  40. +++ agsXMPP2010.sln (revision 0)
  41. @@ -0,0 +1,20 @@
  42. +
  43. +Microsoft Visual Studio Solution File, Format Version 11.00
  44. +# Visual C# Express 2010
  45. +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "agsXMPP2010", "agsXMPP2010.csproj", "{91EA0D0B-D3BA-497F-AFEB-2CAD59DEBA0E}"
  46. +EndProject
  47. +Global
  48. +   GlobalSection(SolutionConfigurationPlatforms) = preSolution
  49. +       Debug|Any CPU = Debug|Any CPU
  50. +       Release|Any CPU = Release|Any CPU
  51. +   EndGlobalSection
  52. +   GlobalSection(ProjectConfigurationPlatforms) = postSolution
  53. +       {91EA0D0B-D3BA-497F-AFEB-2CAD59DEBA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  54. +       {91EA0D0B-D3BA-497F-AFEB-2CAD59DEBA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
  55. +       {91EA0D0B-D3BA-497F-AFEB-2CAD59DEBA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
  56. +       {91EA0D0B-D3BA-497F-AFEB-2CAD59DEBA0E}.Release|Any CPU.Build.0 = Release|Any CPU
  57. +   EndGlobalSection
  58. +   GlobalSection(SolutionProperties) = preSolution
  59. +       HideSolutionNode = FALSE
  60. +   EndGlobalSection
  61. +EndGlobal
  62. Index: Net/BoshClientSocket.cs
  63. ===================================================================
  64. --- Net/BoshClientSocket.cs (revision 129)
  65. +++ Net/BoshClientSocket.cs (working copy)
  66. @@ -433,71 +433,71 @@
  67.              catch (WebException ex)
  68.              {
  69.                  FireOnError(ex);
  70. -                Disconnect();
  71.              }
  72.          }
  73.  
  74.          private void OnGetSessionRequestResponse(IAsyncResult result)
  75.          {
  76. -            // grab the custom state object
  77. -            WebRequestState state = (WebRequestState)result.AsyncState;
  78. -            HttpWebRequest request = (HttpWebRequest)state.WebRequest;
  79. +            try {
  80. +                // grab the custom state object
  81. +                WebRequestState state = (WebRequestState)result.AsyncState;
  82. +                HttpWebRequest request = (HttpWebRequest)state.WebRequest;
  83.  
  84. -            //state.TimeOutTimer.Dispose();
  85. +                //state.TimeOutTimer.Dispose();
  86.  
  87. -            // get the Response
  88. -            HttpWebResponse resp = (HttpWebResponse)request.EndGetResponse(result);
  89. +                // get the Response
  90. +                HttpWebResponse resp = (HttpWebResponse)request.EndGetResponse(result);
  91.  
  92. -            // The server must always return a 200 response code,
  93. -            // sending any session errors as specially-formatted identifiers.
  94. -            if (resp.StatusCode != HttpStatusCode.OK)
  95. -            {
  96. -                //FireOnError(new PollSocketException("unexpected status code " + resp.StatusCode.ToString()));
  97. -                return;
  98. -            }
  99. +                // The server must always return a 200 response code,
  100. +                // sending any session errors as specially-formatted identifiers.
  101. +                if (resp.StatusCode != HttpStatusCode.OK) {
  102. +                    //FireOnError(new PollSocketException("unexpected status code " + resp.StatusCode.ToString()));
  103. +                    return;
  104. +                }
  105.  
  106. -            Stream rs = resp.GetResponseStream();
  107. +                Stream rs = resp.GetResponseStream();
  108.  
  109. -            int readlen;
  110. -            byte[] readbuf = new byte[1024];
  111. -            MemoryStream ms = new MemoryStream();
  112. -            while ((readlen = rs.Read(readbuf, 0, readbuf.Length)) > 0)
  113. -            {
  114. -                ms.Write(readbuf, 0, readlen);
  115. -            }
  116. +                int readlen;
  117. +                byte[] readbuf = new byte[1024];
  118. +                MemoryStream ms = new MemoryStream();
  119. +                while ((readlen = rs.Read(readbuf, 0, readbuf.Length)) > 0) {
  120. +                    ms.Write(readbuf, 0, readlen);
  121. +                }
  122.  
  123. -            byte[] recv = ms.ToArray();
  124. +                byte[] recv = ms.ToArray();
  125.  
  126. -            if (recv.Length > 0)
  127. -            {
  128. -                string body = null;
  129. -                string stanzas = null;
  130. +                if (recv.Length > 0) {
  131. +                    string body = null;
  132. +                    string stanzas = null;
  133.  
  134. -                string res = Encoding.UTF8.GetString(recv, 0, recv.Length);
  135. +                    string res = Encoding.UTF8.GetString(recv, 0, recv.Length);
  136.  
  137. -                ParseResponse(res, ref body, ref stanzas);
  138. -              
  139. -                Document doc = new Document();
  140. -                doc.LoadXml(body);
  141. -                Body boshBody = doc.RootElement as Body;
  142. +                    ParseResponse(res, ref body, ref stanzas);
  143.  
  144. -                sid         = boshBody.Sid;
  145. -                polling     = boshBody.Polling;
  146. -                m_MaxPause  = boshBody.MaxPause;
  147. +                    Document doc = new Document();
  148. +                    doc.LoadXml(body);
  149. +                    Body boshBody = doc.RootElement as Body;
  150.  
  151. -                byte[] bin = Encoding.UTF8.GetBytes(DummyStreamHeader + stanzas);
  152. -                
  153. -                base.FireOnReceive(bin, bin.Length);
  154. +                    sid = boshBody.Sid;
  155. +                    polling = boshBody.Polling;
  156. +                    m_MaxPause = boshBody.MaxPause;
  157.  
  158. -                // cleanup webrequest resources
  159. -                ms.Close();
  160. -                rs.Close();
  161. -                resp.Close();
  162. +                    byte[] bin = Encoding.UTF8.GetBytes(DummyStreamHeader + stanzas);
  163.  
  164. -                activeRequests--;
  165. +                    base.FireOnReceive(bin, bin.Length);
  166.  
  167. -                if (activeRequests == 0)
  168. -                    StartWebRequest();                
  169. +                    // cleanup webrequest resources
  170. +                    ms.Close();
  171. +                    rs.Close();
  172. +                    resp.Close();
  173. +
  174. +                    activeRequests--;
  175. +
  176. +                    if (activeRequests == 0)
  177. +                        StartWebRequest();
  178. +                }
  179. +            } catch (Exception ex) {
  180. +                FireOnError(ex);
  181.              }
  182.          }
  183.  
  184. @@ -714,7 +714,7 @@
  185.              {
  186.                  IAsyncResult result = req.BeginGetRequestStream(new AsyncCallback(this.OnGetRequestStream), state);                
  187.              }
  188. -            catch(Exception ex)
  189. +            catch(Exception )
  190.              {
  191.                  //Console.WriteLine(ex.Message);
  192.              }
  193. @@ -769,7 +769,7 @@
  194.                      IAsyncResult result = requestStream.BeginWrite(bytes, 0, bytes.Length, new AsyncCallback(this.OnEndWrite), state);
  195.                  }
  196.              }
  197. -            catch (Exception ex)
  198. +            catch (Exception )
  199.              {
  200.                  //Console.WriteLine(ex.Message);
  201.                  activeRequests--;
  202. @@ -801,7 +801,7 @@
  203.                      result = req.BeginGetResponse(new AsyncCallback(this.OnGetResponse), state);    
  204.                
  205.              }
  206. -            catch (Exception ex)
  207. +            catch (Exception )
  208.              {
  209.                  //Console.WriteLine(ex.Message);
  210.              }
  211. @@ -935,7 +935,7 @@
  212.                      StartWebRequest();
  213.                  }
  214.              }
  215. -            catch (Exception ex)
  216. +            catch (Exception )
  217.              {
  218.                  //Console.WriteLine("Error in OnGetResponse");
  219.                  //Console.WriteLine(ex.Message);
  220. Index: Net/ClientSocket.cs
  221. ===================================================================
  222. --- Net/ClientSocket.cs (revision 129)
  223. +++ Net/ClientSocket.cs (working copy)
  224. @@ -58,18 +58,18 @@
  225.      /// </summary>
  226.      public class ClientSocket : BaseSocket
  227.      {
  228. -        Socket _socket;
  229. +        protected Socket _socket;
  230.  #if SSL   
  231.          SslStream           m_SSLStream;
  232.  #endif
  233. -        NetworkStream m_Stream;
  234. -        Stream m_NetworkStream = null;
  235. +        protected NetworkStream m_Stream;
  236. +        protected Stream m_NetworkStream = null;
  237.  
  238.  
  239. -        const int BUFFERSIZE = 1024;
  240. -        private byte[] m_ReadBuffer = null;
  241. +        protected const int BUFFERSIZE = 1024;
  242. +        protected byte[] m_ReadBuffer = null;
  243.  
  244. -        private bool m_SSL = false;
  245. +        protected bool m_SSL = false;
  246.  
  247.          private bool m_PendingSend = false;
  248.          private Queue m_SendQueue = new Queue();
  249. @@ -77,9 +77,9 @@
  250.          /// <summary>
  251.          /// is compression used for this connection
  252.          /// </summary>
  253. -        private bool m_Compressed = false;
  254. +        protected bool m_Compressed = false;
  255.  
  256. -        private bool m_ConnectTimedOut = false;
  257. +        protected bool m_ConnectTimedOut = false;
  258.          /// <summary>
  259.          /// is used to compress data
  260.          /// </summary>
  261. @@ -89,7 +89,7 @@
  262.          /// </summary>
  263.          private Inflater inflater = null;
  264.  
  265. -        private Timer connectTimeoutTimer;
  266. +        protected Timer connectTimeoutTimer;
  267.  
  268.  
  269.          #region << Constructor >>
  270. @@ -221,7 +221,7 @@
  271.              }
  272.          }
  273.  
  274. -        private void EndConnect(IAsyncResult ar)
  275. +        protected void EndConnect(IAsyncResult ar)
  276.          {
  277.              if (m_ConnectTimedOut)
  278.              {
  279. @@ -262,7 +262,7 @@
  280.          /// Connect Timeout Timer Callback
  281.          /// </summary>
  282.          /// <param name="stateInfo"></param>
  283. -        private void connectTimeoutTimerDelegate(Object stateInfo)
  284. +        protected void connectTimeoutTimerDelegate(Object stateInfo)
  285.          {
  286.              connectTimeoutTimer.Dispose();
  287.              m_ConnectTimedOut = true;
  288. @@ -284,7 +284,7 @@
  289.         /// <summary>
  290.         ///
  291.         /// </summary>
  292. -       private void InitSSL()
  293. +        protected void InitSSL()
  294.         {
  295.              InitSSL(SslProtocols.Default);
  296.         }        
  297. @@ -293,7 +293,7 @@
  298.         ///
  299.         /// </summary>
  300.         /// <param name="protocol"></param>    
  301. -        private void InitSSL(SslProtocols protocol)
  302. +        protected void InitSSL(SslProtocols protocol)
  303.         {            
  304.             m_SSLStream = new SslStream(
  305.                  m_Stream,
  306. @@ -533,7 +533,7 @@
  307.          /// <summary>
  308.          /// Read data from server.
  309.          /// </summary>
  310. -        private void Receive()
  311. +        protected void Receive()
  312.          {
  313.              m_NetworkStream.BeginRead(m_ReadBuffer, 0, BUFFERSIZE, new AsyncCallback(EndReceive), null);
  314.          }
  315. @@ -574,7 +574,7 @@
  316.                  //object already disposed, just exit
  317.                  return;
  318.              }
  319. -            catch (System.IO.IOException ex)
  320. +            catch (System.IO.IOException)
  321.              {
  322.                  //Console.WriteLine("\nSocket Exception: " + ex.Message);
  323.                  Disconnect();
  324. Index: Net/ConnectClientSocket.cs
  325. ===================================================================
  326. --- Net/ConnectClientSocket.cs  (revision 0)
  327. +++ Net/ConnectClientSocket.cs  (revision 0)
  328. @@ -0,0 +1,167 @@
  329. +using System;
  330. +using System.Net;
  331. +using System.Net.Sockets;
  332. +using System.Threading;
  333. +using System.IO;
  334. +using System.Text;
  335. +using System.Configuration;
  336. +using System.Collections;
  337. +using System.Diagnostics;
  338. +using System.Web;
  339. +
  340. +#if SSL
  341. +using System.Net.Security;
  342. +using System.Security.Authentication;
  343. +using System.Security.Cryptography.X509Certificates;
  344. +#endif
  345. +
  346. +namespace agsXMPP.Net {
  347. +    public class ConnectClientException : Exception {
  348. +        public enum ErrorCode {
  349. +            HTTP_CONNECT,
  350. +            CONNECTION_TIMEDOUT
  351. +        };
  352. +        private static string[] ErrorStrings = new string[] {
  353. +            "Error creating HTTP tunnel",
  354. +            "Conenction timed out"
  355. +        };
  356. +        public ErrorCode HTTPError;
  357. +        public ConnectClientException(ErrorCode err)
  358. +            : base(ErrorStrings[(int)err]) {
  359. +                HTTPError = err;
  360. +        }
  361. +    }
  362. +
  363. +    public class ConnectClientSocket : ClientSocket {
  364. +        public ConnectClientSocket() {
  365. +        }
  366. +
  367. +        public override void Connect() {
  368. +            // Socket is never compressed at startup
  369. +            m_Compressed = false;
  370. +            m_ReadBuffer = null;
  371. +            m_ReadBuffer = new byte[BUFFERSIZE];
  372. +
  373. +            try {
  374. +                IPAddress ipAddress = null;
  375. +                try {
  376. +                    IPHostEntry ipHostInfo = System.Net.Dns.GetHostEntry(Address);
  377. +
  378. +                    if (ipHostInfo.AddressList.Length > 0) {
  379. +                        ipAddress = ipHostInfo.AddressList[0];
  380. +                    } else {
  381. +                        ipAddress = IPAddress.Parse(Address);
  382. +                    }
  383. +                } catch (Exception) {
  384. +                    // just try to assign as IP address
  385. +                    ipAddress = IPAddress.Parse(Address);
  386. +                }
  387. +                IPEndPoint endPoint = new IPEndPoint(ipAddress, Port);
  388. +                // Timeout
  389. +                // .NET supports no timeout for connect, and the default timeout is very high, so it could
  390. +                // take very long to establish the connection with the default timeout. So we handle custom
  391. +                // connect timeouts with a timer
  392. +                m_ConnectTimedOut = false;
  393. +                TimerCallback timerDelegate = new TimerCallback(connectTimeoutTimerDelegate);
  394. +                connectTimeoutTimer = new Timer(timerDelegate, null, ConnectTimeout, ConnectTimeout);
  395. +#if !(CF || CF_2)
  396. +                // IPV6 Support for .NET 2.0
  397. +                if (Socket.OSSupportsIPv6 && (endPoint.AddressFamily == AddressFamily.InterNetworkV6)) {
  398. +                    _socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
  399. +                } else {
  400. +                    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  401. +                }
  402. +#else
  403. +                // CF, there is no IPV6 support yet
  404. +                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  405. +#endif
  406. +                _socket.BeginConnect(endPoint, new AsyncCallback(EndConnect), null);
  407. +            } catch (Exception ex) {
  408. +                FireOnError(ex);
  409. +            }
  410. +        }
  411. +
  412. +        public static string EncodeUIDPWD(string uid, string pwd) {
  413. +            string uidpwd = uid + ":" + pwd;
  414. +            byte[] data = System.Text.UnicodeEncoding.UTF8.GetBytes(uidpwd);
  415. +            StringBuilder sb = new StringBuilder();
  416. +            sb.Append(System.Convert.ToBase64String(data));
  417. +            return (sb.ToString());
  418. +        }
  419. +        
  420. +        public string HTTPConnectAddr = "";
  421. +        public int HTTPConnectPort = 80;
  422. +        public string HTTPProxyUser = "";
  423. +        public string HTTPProxyPass = "";
  424. +
  425. +        private string ReadHTTPAnswer() {
  426. +            byte[] buf = new byte [1] { 0 };
  427. +            int crlfcnt = 0;
  428. +            string answer = "";
  429. +            while (true) {
  430. +                if (_socket.Receive(buf, 1, SocketFlags.None) == 1) {
  431. +                    answer += Encoding.UTF8.GetString(buf);
  432. +                    if (buf[0] == '\n' || buf[0] == '\r') {
  433. +                        crlfcnt++;
  434. +                        if (crlfcnt == 4) {
  435. +                            break;
  436. +                        }
  437. +                    } else {
  438. +                        crlfcnt = 0;
  439. +                    }
  440. +                } else {
  441. +                    break;
  442. +                }
  443. +            }
  444. +            return answer;
  445. +        }
  446. +
  447. +        private void ConnectToHTTPProxy() {
  448. +            // creating request
  449. +            string proxyMsg = "CONNECT " + HTTPConnectAddr + ":" + HTTPConnectPort + " HTTP/1.0\n";
  450. +            // adding some headers
  451. +            proxyMsg += "Host: " + HTTPConnectAddr + "\n";
  452. +            if (HTTPProxyUser.Length > 0) {
  453. +                string EncodedData = EncodeUIDPWD(HTTPProxyUser, HTTPProxyPass);
  454. +                proxyMsg += "Proxy-Authorization:Basic " + EncodedData + "\n";
  455. +            }
  456. +            proxyMsg += "\n";
  457. +            // sending
  458. +            byte[] buffer = Encoding.ASCII.GetBytes(proxyMsg);
  459. +            _socket.Send(buffer, buffer.Length, SocketFlags.None);
  460. +            // receiving answer and analizing
  461. +            string data = ReadHTTPAnswer();
  462. +            if (data.IndexOf("200") == -1) {
  463. +                throw new ConnectClientException(ConnectClientException.ErrorCode.HTTP_CONNECT);
  464. +            }
  465. +        }
  466. +
  467. +        new protected void EndConnect(IAsyncResult ar) {
  468. +            // go do something
  469. +            if (m_ConnectTimedOut) {
  470. +                FireOnError(new ConnectClientException(ConnectClientException.ErrorCode.CONNECTION_TIMEDOUT));
  471. +            } else {
  472. +                try {
  473. +                    // stop the timeout timer
  474. +                    connectTimeoutTimer.Dispose();
  475. +                    // pass connection status with event
  476. +                    _socket.EndConnect(ar);
  477. +                    // try HTTP connect and auth
  478. +                    ConnectToHTTPProxy();
  479. +                    // assing network stream as usual
  480. +                    m_Stream = new NetworkStream(_socket, false);
  481. +                    m_NetworkStream = m_Stream;
  482. +#if SSL
  483. +                    if (m_SSL)
  484. +                        InitSSL();
  485. +#endif
  486. +                    FireOnConnect();
  487. +                    // Setup Receive Callback
  488. +                    Receive();
  489. +                } catch (Exception ex) {
  490. +                    FireOnError(ex);
  491. +                }
  492. +            }
  493. +        }
  494. +    }
  495. +}
  496. Index: Net/SocketConnectionType.cs
  497. ===================================================================
  498. --- Net/SocketConnectionType.cs (revision 129)
  499. +++ Net/SocketConnectionType.cs (working copy)
  500. @@ -34,6 +34,11 @@
  501.         /// </summary>
  502.         Direct,
  503.  #endif
  504. +        /// <summary>
  505. +        /// <para>HTTP tunneling using CONNECT method</para>
  506. +        /// </summary>
  507. +        HttpConnect,
  508. +
  509.         /// <summary>
  510.         /// A HTTP Polling Socket connection (JEP-0025)
  511.         /// </summary>
  512. @@ -43,6 +48,11 @@
  513.          /// <para>XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)</para>
  514.          /// <para>http://www.xmpp.org/extensions/xep-0124.html</para>
  515.          /// </summary>
  516. -        Bosh
  517. +        Bosh,
  518. +
  519. +        /// <summary>
  520. +        /// <para>SOCKS5 proxy</para>
  521. +        /// </summary>
  522. +        SOCKS5
  523.     }
  524.  }
  525. Index: Net/Socks5Socket.cs
  526. ===================================================================
  527. --- Net/Socks5Socket.cs (revision 0)
  528. +++ Net/Socks5Socket.cs (revision 0)
  529. @@ -0,0 +1,307 @@
  530. +using System;
  531. +using System.Net;
  532. +using System.Net.Sockets;
  533. +using System.Threading;
  534. +using System.IO;
  535. +using System.Text;
  536. +using System.Configuration;
  537. +using System.Collections;
  538. +using System.Diagnostics;
  539. +
  540. +#if SSL
  541. +using System.Net.Security;
  542. +using System.Security.Authentication;
  543. +using System.Security.Cryptography.X509Certificates;
  544. +#endif
  545. +
  546. +#if BCCRYPTO
  547. +using Org.BouncyCastle.Crypto.Tls;
  548. +#endif
  549. +
  550. +using agsXMPP.IO.Compression;
  551. +
  552. +using agsXMPP;
  553. +
  554. +namespace agsXMPP.Net {
  555. +    /// <summary>
  556. +    /// Provides sock5 error handling
  557. +    /// </summary>
  558. +    public class Socks5Exception : Exception {
  559. +        /// <summary>
  560. +        /// Socks5 error codes
  561. +        /// </summary>
  562. +        public enum ErrorCode {
  563. +            NO_AUTH_METHODS,
  564. +            BAD_AUTH,
  565. +            GENERAL_FAILURE,
  566. +            CONNECTION_DIBALED,
  567. +            NETWORK_UNREACHABLE,
  568. +            HOST_UNREACHABLE,
  569. +            CONENCTION_FAILED,
  570. +            TTL_EXCEEDED,
  571. +            NOT_SUPPORTED,
  572. +            ADDR_TYPE_NOT_SUPPORTED,
  573. +            CONNECTION_TIMEDOUT
  574. +        };
  575. +
  576. +        private static string[] ErrorStrings = new string[] {
  577. +            "None of the authentication method was accepted by proxy server",
  578. +            "Bad Usernaem/Password",
  579. +            "General server failure",
  580. +            "Connection disabled by rule",
  581. +            "Network unreachable",
  582. +            "Host unreachable",
  583. +            "Connection failed",
  584. +            "TTL exceeded",
  585. +            "Commandnot supported or protocol error",
  586. +            "Address type not supported",
  587. +            "Connection timed out"
  588. +        };
  589. +        public ErrorCode Socks5Error;
  590. +        public Socks5Exception ( ErrorCode err ) : base (ErrorStrings[(int)err]) {
  591. +            Socks5Error = err;
  592. +        }
  593. +    }
  594. +    /// <summary>
  595. +    /// Provides sock5 functionality to clients
  596. +    /// </summary>
  597. +    public class Socks5Socket : ClientSocket {
  598. +        public string socks5host = null;
  599. +        public string socks5user = "";
  600. +        public string socks5pass = "";
  601. +        public ushort socks5port = 1080;
  602. +
  603. +        /// <summary>
  604. +        /// Read and analize last server response
  605. +        /// </summary>
  606. +        private byte GetSocks5Response() {
  607. +            byte[] response = new byte[257];
  608. +            // version
  609. +            _socket.Receive(response, 1, SocketFlags.None); // 1
  610. +            if (response[0] == 0x05) {
  611. +                // read response code
  612. +                _socket.Receive(response, 1, SocketFlags.None); // 2
  613. +                byte retcode = response[0];
  614. +                // reserved
  615. +                _socket.Receive(response, 1, SocketFlags.None);
  616. +                // connect host data
  617. +                _socket.Receive(response, 1, SocketFlags.None);
  618. +                switch (response[0]) {
  619. +                    case 0x01:
  620. +                        // ipv4 address
  621. +                        _socket.Receive(response, 4, SocketFlags.None);
  622. +                        break;
  623. +                    case 0x04:
  624. +                        // ipv6 address
  625. +                        _socket.Receive(response, 16, SocketFlags.None);
  626. +                        break;
  627. +                    case 0x03:
  628. +                        // host len
  629. +                        _socket.Receive(response, 1, SocketFlags.None);
  630. +                        // host
  631. +                        _socket.Receive(response, response[0], SocketFlags.None);
  632. +                        break;
  633. +                    default:
  634. +                        // unknown value
  635. +                        retcode = 0x01;
  636. +                        break;
  637. +                }
  638. +                // port
  639. +                _socket.Receive(response, 2, SocketFlags.None);
  640. +                // return result
  641. +                return retcode;
  642. +            } else {
  643. +                return 0x01;
  644. +            }
  645. +        }
  646. +
  647. +        /// <summary>
  648. +        /// Initialize byte array with 0x00
  649. +        /// </summary>
  650. +        private void Clear(ref byte[] arr) {
  651. +            for (int a = 0; a < arr.Length; a++) {
  652. +                arr[a] = 0x00;
  653. +            }
  654. +        }
  655. +
  656. +        /// <summary>
  657. +        /// Connect to socks5 proxy using specified settings
  658. +        /// </summary>
  659. +        private void ConnectToSocks5Proxy() {
  660. +            byte[] request = new byte[257];
  661. +            byte[] response = new byte[257];
  662. +            byte[] rawBytes = null;
  663. +            ushort nIndex;
  664. +
  665. +            nIndex = 0;
  666. +            // Version 5
  667. +            request[nIndex++] = 0x05;
  668. +            // One authentication methods are in packet...
  669. +            request[nIndex++] = 0x01;
  670. +            if (socks5user.Length != 0 || socks5pass.Length != 0) {
  671. +                // username and password auth
  672. +                request[nIndex++] = 0x02;
  673. +            } else {
  674. +                // no auth
  675. +                request[nIndex++] = 0x00;
  676. +            }
  677. +            // Send the authentication negotiation request...
  678. +            _socket.Send(request, nIndex, SocketFlags.None);
  679. +
  680. +            // Receive 2 byte response...
  681. +            Clear(ref response);
  682. +            _socket.Receive(response, 2, SocketFlags.None);
  683. +            if (response[1] == 0xFF) {
  684. +                // No authentication method was accepted close the socket.
  685. +                throw new Socks5Exception(Socks5Exception.ErrorCode.NO_AUTH_METHODS);
  686. +            }
  687. +
  688. +            // server selected Username/Password Authentication protocol
  689. +            if (response[1] == 0x02) {
  690. +                nIndex = 0;
  691. +                // Version 5
  692. +                request[nIndex++] = 0x05;
  693. +                // add user name
  694. +                request[nIndex++] = (byte)socks5user.Length;
  695. +                rawBytes = Encoding.Default.GetBytes(socks5user);
  696. +                rawBytes.CopyTo(request, nIndex);
  697. +                nIndex += (ushort)rawBytes.Length;
  698. +                // add password
  699. +                request[nIndex++] = (byte)socks5pass.Length;
  700. +                rawBytes = Encoding.Default.GetBytes(socks5pass);
  701. +                rawBytes.CopyTo(request, nIndex);
  702. +                nIndex += (ushort)rawBytes.Length;
  703. +                // Send the Username/Password request
  704. +                _socket.Send(request, nIndex, SocketFlags.None);
  705. +                // Receive 2 byte response
  706. +                Clear(ref response);
  707. +                _socket.Receive(response, 2, SocketFlags.None);
  708. +                if (response[1] != 0x00) {
  709. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.BAD_AUTH);
  710. +                }
  711. +            }
  712. +
  713. +            // Send connect request
  714. +            nIndex = 0;
  715. +            // version 5.
  716. +            request[nIndex++] = 0x05;
  717. +            // command = connect.
  718. +            request[nIndex++] = 0x01;
  719. +            // Reserve = must be 0x00
  720. +            request[nIndex++] = 0x00;
  721. +
  722. +            // Address is full-qualified domain name.
  723. +            request[nIndex++] = 0x03;
  724. +            // length of address.
  725. +            request[nIndex++] = Convert.ToByte(socks5host.Length);
  726. +            rawBytes = Encoding.Default.GetBytes(socks5host);
  727. +            rawBytes.CopyTo(request, nIndex);
  728. +            nIndex += (ushort)rawBytes.Length;
  729. +
  730. +            // using big-edian byte order
  731. +            byte[] portBytes = BitConverter.GetBytes(socks5port);
  732. +            for (int i = portBytes.Length - 1; i >= 0; i--) {
  733. +                request[nIndex++] = portBytes[i];
  734. +            }
  735. +
  736. +            // send connect request.
  737. +            _socket.Send(request, nIndex, SocketFlags.None);
  738. +            byte retcode = GetSocks5Response();
  739. +            // Get variable length response
  740. +            switch (retcode) {
  741. +                case 0x00:
  742. +                    // connected
  743. +                    break;
  744. +                case 0x01:
  745. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.GENERAL_FAILURE);
  746. +                case 0x02:
  747. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.CONNECTION_DIBALED);
  748. +                case 0x03:
  749. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.NETWORK_UNREACHABLE);
  750. +                case 0x04:
  751. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.HOST_UNREACHABLE);
  752. +                case 0x05:
  753. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.CONENCTION_FAILED);
  754. +                case 0x06:
  755. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.TTL_EXCEEDED);
  756. +                case 0x07:
  757. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.NOT_SUPPORTED);
  758. +                case 0x08:
  759. +                    throw new Socks5Exception(Socks5Exception.ErrorCode.ADDR_TYPE_NOT_SUPPORTED);
  760. +            }
  761. +        }
  762. +
  763. +        public override void Connect() {
  764. +            // Socket is never compressed at startup
  765. +            m_Compressed = false;
  766. +            m_ReadBuffer = null;
  767. +            m_ReadBuffer = new byte[BUFFERSIZE];
  768. +
  769. +            try {
  770. +                IPAddress ipAddress = null;
  771. +                try {
  772. +                    IPHostEntry ipHostInfo = System.Net.Dns.GetHostEntry(Address);
  773. +
  774. +                    if (ipHostInfo.AddressList.Length > 0) {
  775. +                        ipAddress = ipHostInfo.AddressList[0];
  776. +                    } else {
  777. +                        ipAddress = IPAddress.Parse(Address);
  778. +                    }
  779. +                } catch (Exception) {
  780. +                    // just try to assign as IP address
  781. +                    ipAddress = IPAddress.Parse(Address);
  782. +                }
  783. +                IPEndPoint endPoint = new IPEndPoint(ipAddress, Port);
  784. +                // Timeout
  785. +                // .NET supports no timeout for connect, and the default timeout is very high, so it could
  786. +                // take very long to establish the connection with the default timeout. So we handle custom
  787. +                // connect timeouts with a timer
  788. +                m_ConnectTimedOut = false;
  789. +                TimerCallback timerDelegate = new TimerCallback(connectTimeoutTimerDelegate);
  790. +                connectTimeoutTimer = new Timer(timerDelegate, null, ConnectTimeout, ConnectTimeout);
  791. +#if !(CF || CF_2)
  792. +                // IPV6 Support for .NET 2.0
  793. +                if (Socket.OSSupportsIPv6 && (endPoint.AddressFamily == AddressFamily.InterNetworkV6)) {
  794. +                    _socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
  795. +                } else {
  796. +                    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  797. +                }
  798. +#else
  799. +                // CF, there is no IPV6 support yet
  800. +                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  801. +#endif
  802. +                _socket.BeginConnect(endPoint, new AsyncCallback(EndConnect), null);
  803. +            } catch (Exception ex) {
  804. +                FireOnError(ex);
  805. +            }
  806. +        }
  807. +
  808. +        new protected void EndConnect(IAsyncResult ar) {
  809. +            // go do something
  810. +            if (m_ConnectTimedOut) {
  811. +                FireOnError(new Socks5Exception(Socks5Exception.ErrorCode.CONNECTION_TIMEDOUT));
  812. +            } else {
  813. +                try {
  814. +                    // stop the timeout timer
  815. +                    connectTimeoutTimer.Dispose();
  816. +                    // pass connection status with event
  817. +                    _socket.EndConnect(ar);
  818. +                    // try socks5 auth
  819. +                    ConnectToSocks5Proxy();
  820. +                    // assing network stream as usual
  821. +                    m_Stream = new NetworkStream(_socket, false);
  822. +                    m_NetworkStream = m_Stream;
  823. +#if SSL
  824. +                    if (m_SSL)
  825. +                        InitSSL();
  826. +#endif
  827. +                    FireOnConnect();
  828. +                    // Setup Receive Callback
  829. +                    Receive();
  830. +                } catch (Exception ex) {
  831. +                    FireOnError(ex);
  832. +                }
  833. +            }
  834. +        }
  835. +    }
  836. +}
  837. Index: XmppClientConnection.cs
  838. ===================================================================
  839. --- XmppClientConnection.cs (revision 129)
  840. +++ XmppClientConnection.cs (working copy)
  841. @@ -742,8 +742,15 @@
  842.  
  843.             StreamParser.Reset();
  844.  #if SSL
  845. -           if (ClientSocket.GetType() == typeof(ClientSocket))
  846. -               ((ClientSocket) ClientSocket).SSL = m_UseSSL;
  847. +            if (ClientSocket.GetType() == typeof(Socks5Socket)) {
  848. +                ((Socks5Socket)ClientSocket).SSL = m_UseSSL;
  849. +            }
  850. +            if (ClientSocket.GetType() == typeof(ConnectClientSocket)) {
  851. +                ((ConnectClientSocket)ClientSocket).SSL = m_UseSSL;
  852. +            }
  853. +            if (ClientSocket.GetType() == typeof(ClientSocket)) {
  854. +                ((ClientSocket)ClientSocket).SSL = m_UseSSL;
  855. +            }
  856.  #endif    
  857.              // this should start later
  858.              //if (m_KeepAlive)
  859. Index: XmppConnection.cs
  860. ===================================================================
  861. --- XmppConnection.cs   (revision 129)
  862. +++ XmppConnection.cs   (working copy)
  863. @@ -328,12 +328,26 @@
  864.             m_ClientSocket = null;
  865.  
  866.             // Socket Stuff
  867. -           if (m_SocketConnectionType == agsXMPP.Net.SocketConnectionType.HttpPolling)
  868. -               m_ClientSocket= new PollClientSocket();            
  869. -            else if (m_SocketConnectionType == agsXMPP.Net.SocketConnectionType.Bosh)
  870. -                m_ClientSocket = new BoshClientSocket(this);
  871. -            else
  872. -                m_ClientSocket = new ClientSocket();
  873. +            switch (m_SocketConnectionType) {
  874. +                case Net.SocketConnectionType.Direct:
  875. +                    m_ClientSocket = new ClientSocket();
  876. +                    break;
  877. +                case Net.SocketConnectionType.HttpPolling:
  878. +                    m_ClientSocket= new PollClientSocket();
  879. +                    break;
  880. +                case Net.SocketConnectionType.Bosh:
  881. +                    m_ClientSocket = new BoshClientSocket(this);
  882. +                    break;
  883. +                case Net.SocketConnectionType.SOCKS5:
  884. +                    m_ClientSocket = new Socks5Socket();
  885. +                    break;
  886. +                case Net.SocketConnectionType.HttpConnect:
  887. +                    m_ClientSocket = new ConnectClientSocket();
  888. +                    break;
  889. +                default:
  890. +                    FireOnError ( this, new Exception( "Can not determine connection type" ));
  891. +                    break;
  892. +            }
  893.        
  894.             m_ClientSocket.OnConnect    += new ObjectHandler(SocketOnConnect);
  895.             m_ClientSocket.OnDisconnect += new ObjectHandler(SocketOnDisconnect);
  896. @@ -360,6 +374,10 @@
  897.         public void SocketDisconnect()
  898.         {
  899.             m_ClientSocket.Disconnect();
  900. +            // this is special case
  901. +            if (m_ConnectionState == agsXMPP.XmppConnectionState.Connecting) {
  902. +                m_ConnectionState = agsXMPP.XmppConnectionState.Disconnected;
  903. +            }
  904.         }
  905.  
  906.         /// <summary>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement