private static void DoTestClientServer(bool fragment)
        {
            SecureRandom secureRandom = new SecureRandom();

            TlsClientProtocol clientProtocol = new TlsClientProtocol(secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(secureRandom);

            clientProtocol.Connect(new MockTlsClient(null));
            serverProtocol.Accept(new MockTlsServer());

            // pump handshake
            bool hadDataFromServer = true;
            bool hadDataFromClient = true;
            while (hadDataFromServer || hadDataFromClient)
            {
                hadDataFromServer = PumpData(serverProtocol, clientProtocol, fragment);
                hadDataFromClient = PumpData(clientProtocol, serverProtocol, fragment);
            }

            // send data in both directions
            byte[] data = new byte[1024];
            secureRandom.NextBytes(data);
            WriteAndRead(clientProtocol, serverProtocol, data, fragment);
            WriteAndRead(serverProtocol, clientProtocol, data, fragment);

            // close the connection
            clientProtocol.Close();
            PumpData(clientProtocol, serverProtocol, fragment);
            CheckClosed(serverProtocol);
            CheckClosed(clientProtocol);
        }
        internal static TlsClientProtocol OpenTlsConnection(string hostname, int port, TlsClient client)
        {
            TcpClient tcp = new TcpClient(hostname, port);

            TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream(), secureRandom);
            protocol.Connect(client);
            return protocol;
        }
        public void TestClientServer()
        {
            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom);

            Server server = new Server(serverProtocol);

            Thread serverThread = new Thread(new ThreadStart(server.Run));
            serverThread.Start();

            MockSrpTlsClient client = new MockSrpTlsClient(null, MockSrpTlsServer.TEST_IDENTITY, MockSrpTlsServer.TEST_PASSWORD);
            clientProtocol.Connect(client);

            // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
            int length = 1000;

            byte[] data = new byte[length];
            secureRandom.NextBytes(data);

            Stream output = clientProtocol.Stream;
            output.Write(data, 0, data.Length);

            byte[] echo = new byte[data.Length];
            int count = Streams.ReadFully(clientProtocol.Stream, echo);

            Assert.AreEqual(count, data.Length);
            Assert.IsTrue(Arrays.AreEqual(data, echo));

            output.Close();

            serverThread.Join();
        }
        public void Connect(HTTPRequest request)
        {
            string negotiatedProtocol = HTTPProtocolFactory.W3C_HTTP1;

            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                request.HasProxy ? request.Proxy.Address :
#endif
                request.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = request.ConnectTimeout;

#if NETFX_CORE
                Client.UseHTTPSProtocol =
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    !Request.UseAlternateSSL &&
#endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Connecting to {1}:{2}", request.CurrentUri.ToString(), uri.Host, uri.Port.ToString()), request.Context);
                }

#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR)
                Client.SendBufferSize    = HTTPManager.SendBufferSize;
                Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize;

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", request.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString()), request.Context);
                }
#endif

#if NETFX_CORE && !UNITY_EDITOR && !ENABLE_IL2CPP
                try
                {
                    Client.Connect(uri.Host, uri.Port);
                }
                finally
                {
                    request.Timing.Add(TimingEventNames.TCP_Connection);
                }
#else
                System.Net.IPAddress[] addresses = null;
                try
                {
                    if (Client.ConnectTimeout > TimeSpan.Zero)
                    {
                        // https://forum.unity3d.com/threads/best-http-released.200006/page-37#post-3150972
                        using (System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false))
                        {
                            IAsyncResult result  = System.Net.Dns.BeginGetHostAddresses(uri.Host, (res) => { try { mre.Set(); } catch { } }, null);
                            bool         success = mre.WaitOne(Client.ConnectTimeout);
                            if (success)
                            {
                                addresses = System.Net.Dns.EndGetHostAddresses(result);
                            }
                            else
                            {
                                throw new TimeoutException("DNS resolve timed out!");
                            }
                        }
                    }
                    else
                    {
                        addresses = System.Net.Dns.GetHostAddresses(uri.Host);
                    }
                }
                finally
                {
                    request.Timing.Add(TimingEventNames.DNS_Lookup);
                }

                if (request.IsCancellationRequested)
                {
                    throw new Exception("IsCancellationRequested");
                }

                try
                {
                    Client.Connect(addresses, uri.Port, request);
                }
                finally
                {
                    request.Timing.Add(TimingEventNames.TCP_Connection);
                }

                if (request.IsCancellationRequested)
                {
                    throw new Exception("IsCancellationRequested");
                }
#endif

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("TCPConnector", "Connected to " + uri.Host + ":" + uri.Port.ToString(), request.Context);
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("TCPConnector", "Already connected to " + uri.Host + ":" + uri.Port.ToString(), request.Context);
            }

            #endregion

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(request.CurrentUri);

                // set the stream to Client.GetStream() so the proxy, if there's any can use it directly.
                this.Stream = this.TopmostStream = Client.GetStream();

                /*if (Stream.CanTimeout)
                 *  Stream.ReadTimeout = Stream.WriteTimeout = (int)Request.Timeout.TotalMilliseconds;*/

#if !BESTHTTP_DISABLE_PROXY
                if (request.HasProxy)
                {
                    try
                    {
                        request.Proxy.Connect(this.Stream, request);
                    }
                    finally
                    {
                        request.Timing.Add(TimingEventNames.Proxy_Negotiation);
                    }
                }

                if (request.IsCancellationRequested)
                {
                    throw new Exception("IsCancellationRequested");
                }
#endif

                // proxy connect is done, we can set the stream to a buffered one. HTTPProxy requires the raw NetworkStream for HTTPResponse's ReadUnknownSize!
                this.Stream = this.TopmostStream = new BufferedReadNetworkStream(Client.GetStream(), Math.Max(8 * 1024, HTTPManager.ReceiveBufferSize));

                // We have to use Request.CurrentUri here, because uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    DateTime tlsNegotiationStartedAt = DateTime.Now;
                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (request.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(this.Stream, new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom());

                        List <string> protocols = new List <string>();
#if !BESTHTTP_DISABLE_HTTP2
                        SupportedProtocols protocol = request.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) : request.ProtocolHandler;
                        if (protocol == SupportedProtocols.HTTP)
                        {
                            // http/2 over tls (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
                            protocols.Add(HTTPProtocolFactory.W3C_HTTP2);
                        }
#endif

                        protocols.Add(HTTPProtocolFactory.W3C_HTTP1);

                        AbstractTlsClient tlsClient = null;
                        if (HTTPManager.TlsClientFactory == null)
                        {
                            tlsClient = HTTPManager.DefaultTlsClientFactory(request, protocols);
                        }
                        else
                        {
                            try
                            {
                                tlsClient = HTTPManager.TlsClientFactory(request, protocols);
                            }
                            catch
                            { }

                            if (tlsClient == null)
                            {
                                tlsClient = HTTPManager.DefaultTlsClientFactory(request, protocols);
                            }
                        }

                        tlsClient.LoggingContext = request.Context;
                        handler.Connect(tlsClient);

                        if (!string.IsNullOrEmpty(tlsClient.ServerSupportedProtocol))
                        {
                            negotiatedProtocol = tlsClient.ServerSupportedProtocol;
                        }

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(request.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(request.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }
                    #endregion

                    request.Timing.Add(TimingEventNames.TLS_Negotiation, DateTime.Now - tlsNegotiationStartedAt);
                }
            }

            this.NegotiatedProtocol = negotiatedProtocol;
        }
        public void Connect(HTTPRequest request)
        {
            string negotiatedProtocol = HTTPProtocolFactory.W3C_HTTP1;

            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                request.HasProxy ? request.Proxy.Address :
#endif
                request.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = request.ConnectTimeout;

#if NETFX_CORE
                Client.UseHTTPSProtocol =
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    !Request.UseAlternateSSL &&
#endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Connecting to {1}:{2}", request.CurrentUri.ToString(), uri.Host, uri.Port.ToString()));
                }

#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR)
                Client.SendBufferSize    = HTTPManager.SendBufferSize;
                Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize;

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("TCPConnector", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", request.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString()));
                }
#endif

                Client.Connect(uri.Host, uri.Port);

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("TCPConnector", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("TCPConnector", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }

            #endregion

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(request.CurrentUri);

                this.Stream = this.TopmostStream = Client.GetStream();

                /*if (Stream.CanTimeout)
                 *  Stream.ReadTimeout = Stream.WriteTimeout = (int)Request.Timeout.TotalMilliseconds;*/


#if !BESTHTTP_DISABLE_PROXY
                if (request.Proxy != null)
                {
                    request.Proxy.Connect(this.Stream, request);
                }
#endif

                // We have to use Request.CurrentUri here, because uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (request.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom());

                        // http://tools.ietf.org/html/rfc3546#section-3.1
                        // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type.
                        // -Literal IPv4 and IPv6 addresses are not permitted in "HostName".

                        // User-defined list has a higher priority
                        List <string> hostNames = request.CustomTLSServerNameList;

                        // If there's no user defined one and the host isn't an IP address, add the default one
                        if ((hostNames == null || hostNames.Count == 0) && !request.CurrentUri.IsHostIsAnIPAddress())
                        {
                            hostNames = new List <string>(1);
                            hostNames.Add(request.CurrentUri.Host);
                        }

                        List <string> protocols = new List <string>();
#if !BESTHTTP_DISABLE_HTTP2
                        SupportedProtocols protocol = request.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) : request.ProtocolHandler;
                        if (protocol == SupportedProtocols.HTTP)
                        {
                            // http/2 over tls (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
                            protocols.Add(HTTPProtocolFactory.W3C_HTTP2);
                        }
#endif

                        protocols.Add(HTTPProtocolFactory.W3C_HTTP1);

                        var tlsClient = new LegacyTlsClient(request.CurrentUri,
                                                            request.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : request.CustomCertificateVerifyer,
                                                            request.CustomClientCredentialsProvider,
                                                            hostNames,
                                                            protocols);
                        handler.Connect(tlsClient);

                        if (!string.IsNullOrEmpty(tlsClient.ServerSupportedProtocol))
                        {
                            negotiatedProtocol = tlsClient.ServerSupportedProtocol;
                        }

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(request.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(request.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }

                    #endregion
                }
            }

            this.NegotiatedProtocol = negotiatedProtocol;
        }
Exemple #6
0
        public void Connect()
        {
            BasicTlsPskIdentity pskIdentity = null;

            if (_userKey != null)
            {
                if (_userKey.HasKeyType((int)COSE.GeneralValuesInt.KeyType_Octet))
                {
                    CBORObject kid = _userKey[COSE.CoseKeyKeys.KeyIdentifier];

                    if (kid != null)
                    {
                        pskIdentity = new BasicTlsPskIdentity(kid.GetByteString(), _userKey[CoseKeyParameterKeys.Octet_k].GetByteString());
                    }
                    else
                    {
                        pskIdentity = new BasicTlsPskIdentity(new byte[0], _userKey[CoseKeyParameterKeys.Octet_k].GetByteString());
                    }
                }
            }

            _tlsSession = new TLSClient(null, pskIdentity);
            _authKey    = _userKey;

            TlsClientProtocol clientProtocol = new TlsClientProtocol(new SecureRandom());

            _client = new TcpClient(_ipEndPoint.AddressFamily);

            _client.Connect(_ipEndPoint);
            _stm = _client.GetStream();

            clientProtocol.Connect(_tlsSession);

            while (_tlsSession.InHandshake)
            {
                bool sleep    = true;
                int  cbToRead = clientProtocol.GetAvailableOutputBytes();
                if (cbToRead != 0)
                {
                    byte[] data   = new byte[cbToRead];
                    int    cbRead = clientProtocol.ReadOutput(data, 0, cbToRead);
                    _stm.Write(data, 0, cbRead);
                    sleep = false;
                }

                if (_stm.DataAvailable)
                {
                    byte[] data   = new byte[1024];
                    int    cbRead = _stm.Read(data, 0, data.Length);
                    Array.Resize(ref data, cbRead);
                    clientProtocol.OfferInput(data);
                    sleep = false;
                }

                if (sleep)
                {
                    Thread.Sleep(100);
                }
            }

            _tlsClient = clientProtocol;

            //  Send over the capability block

            SendCSMSignal();

            //

            if (_toSend != null)
            {
                _queue.Enqueue(_toSend);
                _toSend = null;
            }

            _stm.BeginRead(_buffer, 0, _buffer.Length, ReadCallback, this);

            WriteData();
        }
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            Logger.Debug($"Connecting to {_proxySettings.RemoteHost}:{_proxySettings.RemotePort}");
            var proxyClient = new TcpClient();
            await proxyClient.ConnectAsync(_proxySettings.RemoteHost, _proxySettings.RemotePort);

            var ogStream = proxyClient.GetStream();

            Stream proxyStream = ogStream;

            if (_proxySettings.Secure)
            {
                var protocol = new TlsClientProtocol(proxyStream, new Org.BouncyCastle.Security.SecureRandom());
                protocol.Connect(new BlazeTlsClient());
                proxyStream = protocol.Stream;
            }

            var blazeProtocol = new BlazeProxyProtocol();
            var localReader   = connection.CreateReader();
            var localWriter   = connection.CreateWriter();

            var remoteReader = new ProtocolReader(proxyStream);
            var remoteWriter = new ProtocolWriter(proxyStream);


            while (true)
            {
                try
                {
                    var result = await localReader.ReadAsync(blazeProtocol);

                    var message = result.Message;

                    if (message != null)
                    {
                        var header = message.Header;
                        Logger.Debug(
                            $"Client -> Proxy; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                        var requestPayload = message.Payload;

                        if (!requestPayload.IsEmpty)
                        {
                            if (!_parser.TryParseBody(requestPayload))
                            {
                                Logger.Error("Failed to parse request message");
                            }
                        }

                        await remoteWriter.WriteAsync(blazeProtocol, message);
                    }

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
                finally
                {
                    localReader.Advance();
                }

                do
                {
                    try
                    {
                        var result = await remoteReader.ReadAsync(blazeProtocol);

                        var message = result.Message;

                        if (message != null)
                        {
                            var header = message.Header;
                            Logger.Debug(
                                $"Proxy <- Server; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                            var responsePayload = message.Payload;

                            if (!responsePayload.IsEmpty)
                            {
                                if (!_parser.TryParseBody(responsePayload))
                                {
                                    Logger.Error("Failed to parse response message");
                                }
                            }

                            await localWriter.WriteAsync(blazeProtocol, message);
                        }

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        remoteReader.Advance();
                    }
                } while (ogStream.DataAvailable);
            }
        }
        private void Connect()
        {
            Uri uri = (!this.CurrentRequest.HasProxy) ? this.CurrentRequest.CurrentUri : this.CurrentRequest.Proxy.Address;

            if (this.Client == null)
            {
                this.Client = new TcpClient();
            }
            if (!this.Client.Connected)
            {
                this.Client.ConnectTimeout = this.CurrentRequest.ConnectTimeout;
                this.Client.Connect(uri.Host, uri.Port);
                HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host);
            }
            else
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host);
            }
            object locker = HTTPManager.Locker;

            lock (locker)
            {
                this.StartTime = DateTime.UtcNow;
            }
            if (this.Stream == null)
            {
                if (this.HasProxy && !this.Proxy.IsTransparent)
                {
                    this.Stream = this.Client.GetStream();
                    BinaryWriter binaryWriter = new BinaryWriter(this.Stream);
                    binaryWriter.Write(string.Format("CONNECT {0}:{1} HTTP/1.1", this.CurrentRequest.CurrentUri.Host, this.CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    binaryWriter.Write(HTTPRequest.EOL);
                    binaryWriter.Write(string.Format("Proxy-Connection: Keep-Alive", new object[0]));
                    binaryWriter.Write(HTTPRequest.EOL);
                    binaryWriter.Write(string.Format("Connection: Keep-Alive", new object[0]));
                    binaryWriter.Write(HTTPRequest.EOL);
                    binaryWriter.Write(string.Format("Host: {0}:{1}", this.CurrentRequest.CurrentUri.Host, this.CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    binaryWriter.Write(HTTPRequest.EOL);
                    binaryWriter.Write(HTTPRequest.EOL);
                    binaryWriter.Flush();
                    this.CurrentRequest.ProxyResponse = new HTTPProxyResponse(this.CurrentRequest, this.Stream, false, false);
                    if (!this.CurrentRequest.ProxyResponse.Receive(-1, true))
                    {
                        throw new Exception("Connection to the Proxy Server failed!");
                    }
                    HTTPManager.Logger.Information("HTTPConnection", string.Concat(new object[]
                    {
                        "Proxy returned - status code: ",
                        this.CurrentRequest.ProxyResponse.StatusCode,
                        " message: ",
                        this.CurrentRequest.ProxyResponse.Message
                    }));
                }
                if (HTTPProtocolFactory.IsSecureProtocol(this.CurrentRequest.CurrentUri))
                {
                    if (this.CurrentRequest.UseAlternateSSL)
                    {
                        TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(this.Client.GetStream(), new SecureRandom());
                        List <string>     list = new List <string>(1);
                        list.Add(this.CurrentRequest.CurrentUri.Host);
                        TlsClientProtocol    arg_32B_0 = tlsClientProtocol;
                        ICertificateVerifyer arg_326_0;
                        if (this.CurrentRequest.CustomCertificateVerifyer == null)
                        {
                            ICertificateVerifyer certificateVerifyer = new AlwaysValidVerifyer();
                            arg_326_0 = certificateVerifyer;
                        }
                        else
                        {
                            arg_326_0 = this.CurrentRequest.CustomCertificateVerifyer;
                        }
                        arg_32B_0.Connect(new LegacyTlsClient(arg_326_0, null, list));
                        this.Stream = tlsClientProtocol.Stream;
                    }
                    else
                    {
                        SslStream sslStream = new SslStream(this.Client.GetStream(), false, (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) => this.CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(uri.Host);
                        }
                        this.Stream = sslStream;
                    }
                }
                else
                {
                    this.Stream = this.Client.GetStream();
                }
            }
        }
Exemple #9
0
        public static string DownloadFile(string url, int timeout)
        {
            string response = "";
            Uri    uri      = null;

            // try to pasre url
            try
            {
                uri = new Uri(url);
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
            // create new TCP-Client
            using (var client = new TcpClient(uri.Host, uri.Port))
            {
                var sr       = new SecureRandom();
                var cl       = new OSNTlsClient(uri.Host);
                var protocol = new TlsClientProtocol(client.GetStream(), sr);
                protocol.Connect(cl);

                using (var stream = protocol.Stream)
                {
                    var hdr = new StringBuilder();
                    hdr.AppendLine("GET " + uri.PathAndQuery + " HTTP/1.1");
                    hdr.AppendLine("Host: " + uri.Host);
                    hdr.AppendLine("Content-Type: text/json; charset=utf-8");
                    hdr.AppendLine("Connection: close");
                    hdr.AppendLine();

                    var dataToSend = Encoding.ASCII.GetBytes(hdr.ToString());

                    stream.Write(dataToSend, 0, dataToSend.Length);
                    // set stop watch as timout
                    Stopwatch st = new Stopwatch();
                    st.Start();
                    //read header bytewise
                    string header    = "";
                    int    totalRead = 0;
                    byte[] buff      = new byte[1];
                    do
                    {
                        totalRead = stream.Read(buff, 0, buff.Length);
                        header   += Encoding.ASCII.GetString(buff);
                        if (st.ElapsedMilliseconds > timeout)
                        {
                            throw new TimeoutException("Connection to " + url + " timed out.");
                        }
                    }while (!header.Contains("\r\n\r\n"));
                    int contentlength = 0;
                    if (header.Contains("Transfer-Encoding: chunked"))
                    {
                        // chunked transfer, first line should contain content length
                        string strcontentlength = "";
                        do
                        {
                            totalRead         = stream.Read(buff, 0, buff.Length);
                            strcontentlength += Encoding.ASCII.GetString(buff, 0, buff.Length);
                            if (st.ElapsedMilliseconds > timeout)
                            {
                                throw new TimeoutException("Connection to " + url + " timed out.");
                            }
                        }while (!strcontentlength.Contains("\r\n"));
                        strcontentlength = strcontentlength.Replace("\r\n", "");
                        contentlength    = int.Parse(strcontentlength, System.Globalization.NumberStyles.HexNumber);
                    }
                    else
                    {
                        // get content length from header
                        Regex strcontentlength = new Regex("(?<=Content-Length:\\s)\\d+", RegexOptions.IgnoreCase);
                        contentlength = int.Parse(strcontentlength.Match(header).Value);
                    }
                    // re-assign buffer
                    // read response
                    buff      = new byte[1000];
                    totalRead = 0;
                    do
                    {
                        int    bytesRead = stream.Read(buff, 0, buff.Length);
                        string part      = Encoding.UTF8.GetString(buff, 0, bytesRead);
                        Console.WriteLine(part);
                        response  += part;
                        totalRead += bytesRead;
                        if (st.ElapsedMilliseconds > timeout)
                        {
                            throw new TimeoutException("Connection to " + url + " timed out.");
                        }
                    }while (totalRead < contentlength);
                    // cut response at the end
                    if (response.Contains("\r\n"))
                    {
                        response = response.Substring(0, response.IndexOf("\r\n"));
                    }
                    st.Stop();
                }
            }
            return(response);
        }
Exemple #10
0
        private void Connect()
        {
            Uri uri = (!base.CurrentRequest.HasProxy) ? base.CurrentRequest.CurrentUri : base.CurrentRequest.Proxy.Address;

            if (Client == null)
            {
                Client = new TcpClient();
            }
            if (!Client.Connected)
            {
                Client.ConnectTimeout = base.CurrentRequest.ConnectTimeout;
                Client.Connect(uri.Host, uri.Port);
                if (HTTPManager.Logger.Level <= Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }
            lock (HTTPManager.Locker)
            {
                base.StartTime = DateTime.UtcNow;
            }
            if (Stream == null)
            {
                bool flag = HTTPProtocolFactory.IsSecureProtocol(base.CurrentRequest.CurrentUri);
                if (base.HasProxy && (!base.Proxy.IsTransparent || (flag && base.Proxy.NonTransparentForHTTPS)))
                {
                    Stream = Client.GetStream();
                    BinaryWriter binaryWriter = new BinaryWriter(Stream);
                    bool         flag2;
                    do
                    {
                        flag2 = false;
                        binaryWriter.SendAsASCII($"CONNECT {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port} HTTP/1.1");
                        binaryWriter.Write(HTTPRequest.EOL);
                        binaryWriter.SendAsASCII("Proxy-Connection: Keep-Alive");
                        binaryWriter.Write(HTTPRequest.EOL);
                        binaryWriter.SendAsASCII("Connection: Keep-Alive");
                        binaryWriter.Write(HTTPRequest.EOL);
                        binaryWriter.SendAsASCII($"Host: {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port}");
                        binaryWriter.Write(HTTPRequest.EOL);
                        if (base.HasProxy && base.Proxy.Credentials != null)
                        {
                            switch (base.Proxy.Credentials.Type)
                            {
                            case AuthenticationTypes.Basic:
                                binaryWriter.Write(string.Format("Proxy-Authorization: {0}", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(base.Proxy.Credentials.UserName + ":" + base.Proxy.Credentials.Password))).GetASCIIBytes());
                                binaryWriter.Write(HTTPRequest.EOL);
                                break;

                            case AuthenticationTypes.Unknown:
                            case AuthenticationTypes.Digest:
                            {
                                Digest digest = DigestStore.Get(base.Proxy.Address);
                                if (digest != null)
                                {
                                    string text = digest.GenerateResponseHeader(base.CurrentRequest, base.Proxy.Credentials);
                                    if (!string.IsNullOrEmpty(text))
                                    {
                                        binaryWriter.Write($"Proxy-Authorization: {text}".GetASCIIBytes());
                                        binaryWriter.Write(HTTPRequest.EOL);
                                    }
                                }
                                break;
                            }
                            }
                        }
                        binaryWriter.Write(HTTPRequest.EOL);
                        binaryWriter.Flush();
                        base.CurrentRequest.ProxyResponse = new HTTPResponse(base.CurrentRequest, Stream, isStreamed: false, isFromCache: false);
                        if (!base.CurrentRequest.ProxyResponse.Receive())
                        {
                            throw new Exception("Connection to the Proxy Server failed!");
                        }
                        if (HTTPManager.Logger.Level <= Loglevels.Information)
                        {
                            HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + base.CurrentRequest.ProxyResponse.StatusCode + " message: " + base.CurrentRequest.ProxyResponse.Message);
                        }
                        int statusCode = base.CurrentRequest.ProxyResponse.StatusCode;
                        if (statusCode == 407)
                        {
                            string text2 = DigestStore.FindBest(base.CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate"));
                            if (!string.IsNullOrEmpty(text2))
                            {
                                Digest orCreate = DigestStore.GetOrCreate(base.Proxy.Address);
                                orCreate.ParseChallange(text2);
                                if (base.Proxy.Credentials != null && orCreate.IsUriProtected(base.Proxy.Address) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale))
                                {
                                    flag2 = true;
                                }
                            }
                        }
                        else if (!base.CurrentRequest.ProxyResponse.IsSuccess)
                        {
                            throw new Exception($"Proxy returned Status Code: \"{base.CurrentRequest.ProxyResponse.StatusCode}\", Message: \"{base.CurrentRequest.ProxyResponse.Message}\" and Response: {base.CurrentRequest.ProxyResponse.DataAsText}");
                        }
                    }while (flag2);
                }
                if (flag)
                {
                    if (base.CurrentRequest.UseAlternateSSL)
                    {
                        TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(Client.GetStream(), new SecureRandom());
                        List <string>     list = new List <string>(1);
                        list.Add(base.CurrentRequest.CurrentUri.Host);
                        TlsClientProtocol tlsClientProtocol2 = tlsClientProtocol;
                        Uri    currentUri = base.CurrentRequest.CurrentUri;
                        object verifyer;
                        if (base.CurrentRequest.CustomCertificateVerifyer == null)
                        {
                            ICertificateVerifyer certificateVerifyer = new AlwaysValidVerifyer();
                            verifyer = certificateVerifyer;
                        }
                        else
                        {
                            verifyer = base.CurrentRequest.CustomCertificateVerifyer;
                        }
                        tlsClientProtocol2.Connect(new LegacyTlsClient(currentUri, (ICertificateVerifyer)verifyer, base.CurrentRequest.CustomClientCredentialsProvider, list));
                        Stream = tlsClientProtocol.Stream;
                    }
                    else
                    {
                        SslStream sslStream = new SslStream(Client.GetStream(), leaveInnerStreamOpen: false, (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) => base.CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(base.CurrentRequest.CurrentUri.Host);
                        }
                        Stream = sslStream;
                    }
                }
                else
                {
                    Stream = Client.GetStream();
                }
            }
        }
        private void Connect()
        {
            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address :
#endif
                CurrentRequest.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

#if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR)
                Client.UseHTTPSProtocol =
                #if !BESTHTTP_DISABLE_ALTERNATE_SSL
                    !CurrentRequest.UseAlternateSSL &&
                #endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                Client.Connect(uri.Host, uri.Port);

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }

            #endregion

            lock (HTTPManager.Locker)
                StartTime = DateTime.UtcNow;

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri);

#if !BESTHTTP_DISABLE_PROXY
                #region Proxy Handling

                if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS)))
                {
                    Stream = Client.GetStream();
                    var outStream = new BinaryWriter(Stream);

                    bool retry;
                    do
                    {
                        // If we have to becouse of a authentication request, we will switch it to true
                        retry = false;

                        outStream.SendAsASCII(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port));
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Proxy-Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port));
                        outStream.Write(HTTPRequest.EOL);

                        // Proxy Authentication
                        if (HasProxy && Proxy.Credentials != null)
                        {
                            switch (Proxy.Credentials.Type)
                            {
                            case AuthenticationTypes.Basic:
                                // With Basic authentication we don't want to wait for a challange, we will send the hash with the first request
                                outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes());
                                outStream.Write(HTTPRequest.EOL);
                                break;

                            case AuthenticationTypes.Unknown:
                            case AuthenticationTypes.Digest:
                                var digest = DigestStore.Get(Proxy.Address);
                                if (digest != null)
                                {
                                    string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials);
                                    if (!string.IsNullOrEmpty(authentication))
                                    {
                                        outStream.Write(string.Format("Proxy-Authorization: {0}", authentication).GetASCIIBytes());
                                        outStream.Write(HTTPRequest.EOL);
                                    }
                                }

                                break;
                            }
                        }

                        outStream.Write(HTTPRequest.EOL);

                        // Make sure to send all the wrote data to the wire
                        outStream.Flush();

                        CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false);

                        // Read back the response of the proxy
                        if (!CurrentRequest.ProxyResponse.Receive(-1, true))
                        {
                            throw new Exception("Connection to the Proxy Server failed!");
                        }

                        if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                        {
                            HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message);
                        }

                        switch (CurrentRequest.ProxyResponse.StatusCode)
                        {
                        // Proxy authentication required
                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8
                        case 407:
                        {
                            string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate"));
                            if (!string.IsNullOrEmpty(authHeader))
                            {
                                var digest = DigestStore.GetOrCreate(Proxy.Address);
                                digest.ParseChallange(authHeader);

                                if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale))
                                {
                                    retry = true;
                                }
                            }
                            break;
                        }

                        default:
                            if (!CurrentRequest.ProxyResponse.IsSuccess)
                            {
                                throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText));
                            }
                            break;
                        }
                    } while (retry);
                }
                #endregion
#endif // #if !BESTHTTP_DISABLE_PROXY

                // We have to use CurrentRequest.CurrentUri here, becouse uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL
                    if (CurrentRequest.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom());

                        // http://tools.ietf.org/html/rfc3546#section-3.1
                        // It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type.
                        List <string> hostNames = new List <string>(1);
                        hostNames.Add(CurrentRequest.CurrentUri.Host);

                        handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri,
                                                            CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer,
                                                            null,
                                                            hostNames));

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE && !UNITY_WP8
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }

                    #endregion
                }
                else
                {
                    Stream = Client.GetStream();
                }
            }
        }
Exemple #12
0
        Connect()
        {
            Uri uri = CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : CurrentRequest.CurrentUri;

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

//#if NETFX_CORE
                //await
//#endif
                Client.Connect(uri.Host, uri.Port);
            }

            if (Stream == null)
            {
                if (HasProxy && !Proxy.IsTransparent)
                {
                    Stream = Client.GetStream();

                    var outStream = new BinaryWriter(Stream);
                    outStream.Write(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    outStream.Write(HTTPRequest.EOL);
                    outStream.Write(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    outStream.Write(HTTPRequest.EOL);
                    outStream.Write(string.Format("Proxy-Connection: Keep-Alive"));
                    outStream.Write(HTTPRequest.EOL);
                    outStream.Write(HTTPRequest.EOL);
                    outStream.Flush();

                    ReadTo(Stream, HTTPResponse.LF);
                    ReadTo(Stream, HTTPResponse.LF);
                }

                if (HTTPProtocolFactory.IsSecureProtocol(uri))
                {
                    // On WP8 there are no Mono, so we must use the 'alternate' TlsHandlers
#if !UNITY_WP8 && !NETFX_CORE
                    if (CurrentRequest.UseAlternateSSL)
                    {
#endif
                    var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom());
                    handler.Connect(new LegacyTlsClient(new AlwaysValidVerifyer()));
                    Stream = handler.Stream;
#if !UNITY_WP8 && !NETFX_CORE
                }
                else
                {
                    SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                    {
                        return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                    });

                    if (!sslStream.IsAuthenticated)
                    {
                        sslStream.AuthenticateAsClient(uri.Host);
                    }
                    Stream = sslStream;
                }
#endif
                }
                else
                {
                    Stream = Client.GetStream();
                }
            }
        }
        private void Connect()
        {
            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address :
#endif
                CurrentRequest.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

#if NETFX_CORE
                Client.UseHTTPSProtocol =
                #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    !CurrentRequest.UseAlternateSSL &&
                #endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Connecting to {1}:{2}", this.CurrentRequest.CurrentUri.ToString(), uri.Host, uri.Port.ToString()));
                }

#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR)
                Client.SendBufferSize    = HTTPManager.SendBufferSize;
                Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize;

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", this.CurrentRequest.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString()));
                }
#endif

                Client.Connect(uri.Host, uri.Port);

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }

            #endregion

            StartTime = DateTime.UtcNow;

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri);

                Stream = Client.GetStream();

                /*if (Stream.CanTimeout)
                 *  Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;*/


#if !BESTHTTP_DISABLE_PROXY
                if (CurrentRequest.Proxy != null)
                {
                    CurrentRequest.Proxy.Connect(this.Stream, this.CurrentRequest);
                }
#endif

                // We have to use CurrentRequest.CurrentUri here, because uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    // Under the new experimental runtime there's a bug in the Socket.Send implementation that can cause a
                    //  connection when the TLS protocol is used.
#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) && NET_4_6
                    //Client.SendBufferSize = 0;
#endif

                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (CurrentRequest.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new BestHTTP.SecureProtocol.Org.BouncyCastle.Security.SecureRandom());

                        // http://tools.ietf.org/html/rfc3546#section-3.1
                        // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type.
                        // -Literal IPv4 and IPv6 addresses are not permitted in "HostName".

                        // User-defined list has a higher priority
                        List <string> hostNames = CurrentRequest.CustomTLSServerNameList;

                        // If there's no user defined one and the host isn't an IP address, add the default one
                        if ((hostNames == null || hostNames.Count == 0) && !CurrentRequest.CurrentUri.IsHostIsAnIPAddress())
                        {
                            hostNames = new List <string>(1);
                            hostNames.Add(CurrentRequest.CurrentUri.Host);
                        }

                        handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri,
                                                            CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer,
                                                            CurrentRequest.CustomClientCredentialsProvider,
                                                            hostNames));

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }

                    #endregion
                }
            }
        }
        private void Connect()
        {
            Uri uri = !base.CurrentRequest.HasProxy ? base.CurrentRequest.CurrentUri : base.CurrentRequest.Proxy.Address;

            if (this.Client == null)
            {
                this.Client = new TcpClient();
            }
            if (!this.Client.Connected)
            {
                this.Client.ConnectTimeout = base.CurrentRequest.ConnectTimeout;
                if (HTTPManager.Logger.Level == Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("HTTPConnection", $"'{base.CurrentRequest.CurrentUri.ToString()}' - Connecting to {uri.Host}:{uri.Port.ToString()}");
                }
                this.Client.Connect(uri.Host, uri.Port);
                if (HTTPManager.Logger.Level <= Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }
            base.StartTime = DateTime.UtcNow;
            if (this.Stream == null)
            {
                bool flag = HTTPProtocolFactory.IsSecureProtocol(base.CurrentRequest.CurrentUri);
                this.Stream = this.Client.GetStream();
                if (base.HasProxy && (!base.Proxy.IsTransparent || (flag && base.Proxy.NonTransparentForHTTPS)))
                {
                    bool         flag2;
                    BinaryWriter stream = new BinaryWriter(this.Stream);
                    do
                    {
                        flag2 = false;
                        string str = $"CONNECT {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port} HTTP/1.1";
                        HTTPManager.Logger.Information("HTTPConnection", "Sending " + str);
                        stream.SendAsASCII(str);
                        stream.Write(HTTPRequest.EOL);
                        stream.SendAsASCII("Proxy-Connection: Keep-Alive");
                        stream.Write(HTTPRequest.EOL);
                        stream.SendAsASCII("Connection: Keep-Alive");
                        stream.Write(HTTPRequest.EOL);
                        stream.SendAsASCII($"Host: {base.CurrentRequest.CurrentUri.Host}:{base.CurrentRequest.CurrentUri.Port}");
                        stream.Write(HTTPRequest.EOL);
                        if (base.HasProxy && (base.Proxy.Credentials != null))
                        {
                            switch (base.Proxy.Credentials.Type)
                            {
                            case AuthenticationTypes.Basic:
                                stream.Write($"Proxy-Authorization: {("Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(base.Proxy.Credentials.UserName + ":" + base.Proxy.Credentials.Password)))}".GetASCIIBytes());
                                stream.Write(HTTPRequest.EOL);
                                break;

                            case AuthenticationTypes.Unknown:
                            case AuthenticationTypes.Digest:
                            {
                                Digest digest = DigestStore.Get(base.Proxy.Address);
                                if (digest != null)
                                {
                                    string str2 = digest.GenerateResponseHeader(base.CurrentRequest, base.Proxy.Credentials);
                                    if (!string.IsNullOrEmpty(str2))
                                    {
                                        stream.Write($"Proxy-Authorization: {str2}".GetASCIIBytes());
                                        stream.Write(HTTPRequest.EOL);
                                    }
                                }
                                break;
                            }
                            }
                        }
                        stream.Write(HTTPRequest.EOL);
                        stream.Flush();
                        base.CurrentRequest.ProxyResponse = new HTTPResponse(base.CurrentRequest, this.Stream, false, false);
                        if (!base.CurrentRequest.ProxyResponse.Receive(-1, true))
                        {
                            throw new Exception("Connection to the Proxy Server failed!");
                        }
                        if (HTTPManager.Logger.Level <= Loglevels.Information)
                        {
                            object[] objArray1 = new object[] { "Proxy returned - status code: ", base.CurrentRequest.ProxyResponse.StatusCode, " message: ", base.CurrentRequest.ProxyResponse.Message };
                            HTTPManager.Logger.Information("HTTPConnection", string.Concat(objArray1));
                        }
                        if (base.CurrentRequest.ProxyResponse.StatusCode == 0x197)
                        {
                            string str3 = DigestStore.FindBest(base.CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate"));
                            if (!string.IsNullOrEmpty(str3))
                            {
                                Digest orCreate = DigestStore.GetOrCreate(base.Proxy.Address);
                                orCreate.ParseChallange(str3);
                                if (((base.Proxy.Credentials != null) && orCreate.IsUriProtected(base.Proxy.Address)) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale))
                                {
                                    flag2 = true;
                                }
                            }
                        }
                        else if (!base.CurrentRequest.ProxyResponse.IsSuccess)
                        {
                            throw new Exception($"Proxy returned Status Code: " { base.CurrentRequest.ProxyResponse.StatusCode } ", Message: " { base.CurrentRequest.ProxyResponse.Message } " and Response: {base.CurrentRequest.ProxyResponse.DataAsText}");
                        }
                    }while (flag2);
                }
                if (flag)
                {
                    if (base.CurrentRequest.UseAlternateSSL)
                    {
                        TlsClientProtocol protocol  = new TlsClientProtocol(this.Client.GetStream(), new SecureRandom());
                        List <string>     hostNames = new List <string>(1)
                        {
                            base.CurrentRequest.CurrentUri.Host
                        };
                        protocol.Connect(new LegacyTlsClient(base.CurrentRequest.CurrentUri, (base.CurrentRequest.CustomCertificateVerifyer != null) ? base.CurrentRequest.CustomCertificateVerifyer : new AlwaysValidVerifyer(), base.CurrentRequest.CustomClientCredentialsProvider, hostNames));
                        this.Stream = protocol.Stream;
                    }
                    else
                    {
                        SslStream stream = new SslStream(this.Client.GetStream(), false, (sender, cert, chain, errors) => base.CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        if (!stream.IsAuthenticated)
                        {
                            stream.AuthenticateAsClient(base.CurrentRequest.CurrentUri.Host);
                        }
                        this.Stream = stream;
                    }
                }
            }
        }
Exemple #15
0
        private void Connect()
        {
            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address :
#endif
                CurrentRequest.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

#if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR)
                Client.UseHTTPSProtocol =
                #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    !CurrentRequest.UseAlternateSSL &&
                #endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Connecting to {1}:{2}", this.CurrentRequest.CurrentUri.ToString(), uri.Host, uri.Port.ToString()));
                }

#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR)
                Client.SendBufferSize    = HTTPManager.SendBufferSize;
                Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize;

                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", this.CurrentRequest.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString()));
                }
#endif

                Client.Connect(uri.Host, uri.Port);

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }

            #endregion

            StartTime = DateTime.UtcNow;

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri);

                Stream = Client.GetStream();

                /*if (Stream.CanTimeout)
                 *  Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;*/


#if !BESTHTTP_DISABLE_PROXY
                #region Proxy Handling

                if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS)))
                {
                    var outStream = new BinaryWriter(Stream);

                    bool retry;
                    do
                    {
                        // If we have to because of a authentication request, we will switch it to true
                        retry = false;

                        string connectStr = string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port);

                        HTTPManager.Logger.Information("HTTPConnection", "Sending " + connectStr);

                        outStream.SendAsASCII(connectStr);
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Proxy-Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port));
                        outStream.Write(HTTPRequest.EOL);

                        // Proxy Authentication
                        if (HasProxy && Proxy.Credentials != null)
                        {
                            switch (Proxy.Credentials.Type)
                            {
                            case AuthenticationTypes.Basic:
                                // With Basic authentication we don't want to wait for a challenge, we will send the hash with the first request
                                outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes());
                                outStream.Write(HTTPRequest.EOL);
                                break;

                            case AuthenticationTypes.Unknown:
                            case AuthenticationTypes.Digest:
                                var digest = DigestStore.Get(Proxy.Address);
                                if (digest != null)
                                {
                                    string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials, true);
                                    if (!string.IsNullOrEmpty(authentication))
                                    {
                                        string auth = string.Format("Proxy-Authorization: {0}", authentication);
                                        if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                                        {
                                            HTTPManager.Logger.Information("HTTPConnection", "Sending proxy authorization header: " + auth);
                                        }

                                        outStream.Write(auth.GetASCIIBytes());
                                        outStream.Write(HTTPRequest.EOL);
                                    }
                                }

                                break;
                            }
                        }

                        outStream.Write(HTTPRequest.EOL);

                        // Make sure to send all the wrote data to the wire
                        outStream.Flush();

                        CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false);

                        // Read back the response of the proxy
                        if (!CurrentRequest.ProxyResponse.Receive(-1, true))
                        {
                            throw new Exception("Connection to the Proxy Server failed!");
                        }

                        if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                        {
                            HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message + " Body: " + CurrentRequest.ProxyResponse.DataAsText);
                        }

                        switch (CurrentRequest.ProxyResponse.StatusCode)
                        {
                        // Proxy authentication required
                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8
                        case 407:
                        {
                            string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate"));
                            if (!string.IsNullOrEmpty(authHeader))
                            {
                                var digest = DigestStore.GetOrCreate(Proxy.Address);
                                digest.ParseChallange(authHeader);

                                if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale))
                                {
                                    retry = true;
                                }
                            }
                            break;
                        }

                        default:
                            if (!CurrentRequest.ProxyResponse.IsSuccess)
                            {
                                throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText));
                            }
                            break;
                        }
                    } while (retry);
                }
                #endregion
#endif // #if !BESTHTTP_DISABLE_PROXY

                // We have to use CurrentRequest.CurrentUri here, because uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    // Under the new experimental runtime there's a bug in the Socket.Send implementation that can cause a
                    //  connection when the TLS protocol is used.
#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) && NET_4_6
                    //Client.SendBufferSize = 0;
#endif

                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (CurrentRequest.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom());

                        // http://tools.ietf.org/html/rfc3546#section-3.1
                        // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type.
                        // -Literal IPv4 and IPv6 addresses are not permitted in "HostName".

                        // User-defined list has a higher priority
                        List <string> hostNames = CurrentRequest.CustomTLSServerNameList;

                        // If there's no user defined one and the host isn't an IP address, add the default one
                        if ((hostNames == null || hostNames.Count == 0) && !CurrentRequest.CurrentUri.IsHostIsAnIPAddress())
                        {
                            hostNames = new List <string>(1);
                            hostNames.Add(CurrentRequest.CurrentUri.Host);
                        }

                        handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri,
                                                            CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer,
                                                            CurrentRequest.CustomClientCredentialsProvider,
                                                            hostNames));

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE && !UNITY_WP8
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }

                    #endregion
                }
            }
        }
        public void RunTest(TlsTestConfig config)
        {
            CheckTlsVersion(config.clientMinimumVersion);
            CheckTlsVersion(config.clientOfferVersion);
            CheckTlsVersion(config.serverMaximumVersion);
            CheckTlsVersion(config.serverMinimumVersion);

            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            NetworkStream clientNet = new NetworkStream(clientPipe);
            NetworkStream serverNet = new NetworkStream(serverPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom);

            TlsTestClientImpl clientImpl = new TlsTestClientImpl(config);
            TlsTestServerImpl serverImpl = new TlsTestServerImpl(config);

            Server server = new Server(this, serverProtocol, serverImpl);

            Thread serverThread = new Thread(new ThreadStart(server.Run));
            serverThread.Start();

            Exception caught = null;
            try
            {
                clientProtocol.Connect(clientImpl);

                // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
                int length = 1000;

                byte[] data = new byte[length];
                secureRandom.NextBytes(data);
    
                Stream output = clientProtocol.Stream;
                output.Write(data, 0, data.Length);

                byte[] echo = new byte[data.Length];
                int count = Streams.ReadFully(clientProtocol.Stream, echo);

                Assert.AreEqual(count, data.Length);
                Assert.IsTrue(Arrays.AreEqual(data, echo));

                output.Close();
            }
            catch (Exception e)
            {
                caught = e;
                LogException(caught);
            }

            server.AllowExit();
            serverThread.Join();

            Assert.IsTrue(clientNet.IsClosed, "Client Stream not closed");
            Assert.IsTrue(serverNet.IsClosed, "Server Stream not closed");

            Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end");
            Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end");

            Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description");
            Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description");

            if (config.expectFatalAlertConnectionEnd == -1)
            {
                Assert.IsNull(caught, "Unexpected client exception");
                Assert.IsNull(server.mCaught, "Unexpected server exception");
            }
        }
Exemple #17
0
        public void RunTest(TlsTestConfig config)
        {
            CheckTlsVersion(config.clientMinimumVersion);
            CheckTlsVersion(config.clientOfferVersion);
            CheckTlsVersion(config.serverMaximumVersion);
            CheckTlsVersion(config.serverMinimumVersion);

            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            NetworkStream clientNet = new NetworkStream(clientPipe);
            NetworkStream serverNet = new NetworkStream(serverPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom);

            TlsTestClientImpl clientImpl = new TlsTestClientImpl(config);
            TlsTestServerImpl serverImpl = new TlsTestServerImpl(config);

            Server server = new Server(this, serverProtocol, serverImpl);

            Thread serverThread = new Thread(new ThreadStart(server.Run));

            serverThread.Start();

            Exception caught = null;

            try
            {
                clientProtocol.Connect(clientImpl);

                // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
                int length = 1000;

                byte[] data = new byte[length];
                secureRandom.NextBytes(data);

                Stream output = clientProtocol.Stream;
                output.Write(data, 0, data.Length);

                byte[] echo  = new byte[data.Length];
                int    count = Streams.ReadFully(clientProtocol.Stream, echo);

                Assert.AreEqual(count, data.Length);
                Assert.IsTrue(Arrays.AreEqual(data, echo));

                output.Close();
            }
            catch (Exception e)
            {
                caught = e;
                LogException(caught);
            }

            server.AllowExit();
            serverThread.Join();

            Assert.IsTrue(clientNet.IsClosed, "Client Stream not closed");
            Assert.IsTrue(serverNet.IsClosed, "Server Stream not closed");

            Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end");
            Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end");

            Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description");
            Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description");

            if (config.expectFatalAlertConnectionEnd == -1)
            {
                Assert.IsNull(caught, "Unexpected client exception");
                Assert.IsNull(server.mCaught, "Unexpected server exception");
            }
        }