// guarantees to close the socket on error public static void TlsConnect(Socket sock, string host, RemoteCertificateValidationCallback rcvc, Action<Exception,SslStream> cb) { SslStream ssl = null; try { ssl = new SslStream (new NetworkStream (sock, true), false, rcvc); ssl.BeginAuthenticateAsClient (host, (ar) => { try { ssl.EndAuthenticateAsClient (ar); } catch (Exception ex) { ssl.Dispose (); sock.Dispose (); cb (ex, null); return; } cb (null, ssl); }, null); } catch (Exception ex) { if (ssl != null) ssl.Dispose (); sock.Dispose (); cb (ex, null); } }
public void Connect(string user, string password, Region region, string clientVersion) { if (!isConnected) { Thread t = new Thread(() => { this.user = user; this.password = password; this.clientVersion = clientVersion; //this.server = "127.0.0.1"; this.server = RegionInfo.GetServerValue(region); this.loginQueue = RegionInfo.GetLoginQueueValue(region); this.locale = RegionInfo.GetLocaleValue(region); this.useGarena = RegionInfo.GetUseGarenaValue(region); //Sets up our sslStream to riots servers try { client = new TcpClient(server, 2099); } catch { Error("Riots servers are currently unavailable.", ErrorType.AuthKey); Disconnect(); return; } //Check for riot webserver status //along with gettin out Auth Key that we need for the login process. if (useGarena) if (!GetGarenaToken()) return; if (!GetAuthKey()) return; if (!GetIpAddress()) return; sslStream = new SslStream(client.GetStream(), false, AcceptAllCertificates); var ar = sslStream.BeginAuthenticateAsClient(server, null, null); using (ar.AsyncWaitHandle) { if (ar.AsyncWaitHandle.WaitOne(-1)) { sslStream.EndAuthenticateAsClient(ar); } } if (!Handshake()) return; BeginReceive(); if (!SendConnect()) return; if (!Login()) return; //StartHeartbeat(); }); t.IsBackground = true; t.Start(); } }
private Task<bool> ConnectSsl() { _logger.Verbose("Socket connected, starting SSL client authentication"); //Stream mode: not the most performant but it has ssl support var targetHost = IPEndPoint.Address.ToString(); //HostNameResolver is a sync operation but it can block //Use another thread return Task.Factory.StartNew(() => { try { targetHost = SSLOptions.HostNameResolver(IPEndPoint.Address); } catch (Exception ex) { _logger.Error(String.Format("SSL connection: Can not resolve host name for address {0}. Using the IP address instead of the host name. This may cause RemoteCertificateNameMismatch error during Cassandra host authentication. Note that the Cassandra node SSL certificate's CN(Common Name) must match the Cassandra node hostname.", targetHost), ex); } return true; }).Then(_ => { _logger.Verbose("Starting SSL authentication"); var tcs = new TaskCompletionSource<bool>(); var sslStream = new SslStream(new NetworkStream(_socket), false, SSLOptions.RemoteCertValidationCallback, null); _socketStream = sslStream; sslStream.BeginAuthenticateAsClient(targetHost, SSLOptions.CertificateCollection, SSLOptions.SslProtocol, SSLOptions.CheckCertificateRevocation, sslAsyncResult => { try { sslStream.EndAuthenticateAsClient(sslAsyncResult); tcs.TrySetResult(true); } catch (Exception ex) { tcs.TrySetException(ex); } }, null); return tcs.Task; }).ContinueSync(_ => { _logger.Verbose("SSL authentication successful"); ReceiveAsync(); return true; }); }
private Stream NegotiateStream(Stream stream) { if (!_sslEnabled) return stream; var validateRemoteCertificate = new RemoteCertificateValidationCallback( (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { if (sslPolicyErrors == SslPolicyErrors.None) return true; if (_configuration.SslPolicyErrorsBypassed) return true; else _log(string.Format("Error occurred when validating remote certificate: [{0}], [{1}].", this.RemoteEndPoint, sslPolicyErrors)); return false; }); var sslStream = new SslStream( stream, false, validateRemoteCertificate, null); IAsyncResult ar = null; if (_configuration.SslClientCertificates == null || _configuration.SslClientCertificates.Count == 0) { ar = sslStream.BeginAuthenticateAsClient( // No client certificates are used in the authentication. The certificate revocation list is not checked during authentication. _configuration.SslTargetHost, // The name of the server that will share this SslStream. The value specified for targetHost must match the name on the server's certificate. null, _tcpClient); } else { ar = sslStream.BeginAuthenticateAsClient( _configuration.SslTargetHost, // The name of the server that will share this SslStream. The value specified for targetHost must match the name on the server's certificate. _configuration.SslClientCertificates, // The X509CertificateCollection that contains client certificates. _configuration.SslEnabledProtocols, // The SslProtocols value that represents the protocol used for authentication. _configuration.SslCheckCertificateRevocation, // A Boolean value that specifies whether the certificate revocation list is checked during authentication. null, _tcpClient); } if (!ar.AsyncWaitHandle.WaitOne(ConnectTimeout)) { Close(WebSocketCloseCode.TlsHandshakeFailed, "SSL/TLS handshake timeout."); throw new TimeoutException(string.Format( "Negotiate SSL/TSL with remote [{0}] timeout [{1}].", this.RemoteEndPoint, ConnectTimeout)); } sslStream.EndAuthenticateAsClient(ar); // When authentication succeeds, you must check the IsEncrypted and IsSigned properties // to determine what security services are used by the SslStream. // Check the IsMutuallyAuthenticated property to determine whether mutual authentication occurred. _log(string.Format( "Ssl Stream: SslProtocol[{0}], IsServer[{1}], IsAuthenticated[{2}], IsEncrypted[{3}], IsSigned[{4}], IsMutuallyAuthenticated[{5}], " + "HashAlgorithm[{6}], HashStrength[{7}], KeyExchangeAlgorithm[{8}], KeyExchangeStrength[{9}], CipherAlgorithm[{10}], CipherStrength[{11}].", sslStream.SslProtocol, sslStream.IsServer, sslStream.IsAuthenticated, sslStream.IsEncrypted, sslStream.IsSigned, sslStream.IsMutuallyAuthenticated, sslStream.HashAlgorithm, sslStream.HashStrength, sslStream.KeyExchangeAlgorithm, sslStream.KeyExchangeStrength, sslStream.CipherAlgorithm, sslStream.CipherStrength)); return sslStream; }