static string PostStream(Mono.Security.Protocol.Tls.SecurityProtocolType protocol, string url, byte[] buffer) { Uri uri = new Uri(url); string post = "POST " + uri.AbsolutePath + " HTTP/1.0\r\n"; post += "Content-Type: application/x-www-form-urlencoded\r\n"; post += "Content-Length: " + (buffer.Length + 5).ToString() + "\r\n"; post += "Host: " + uri.Host + "\r\n\r\n"; post += "TEST="; byte[] bytes = Encoding.Default.GetBytes(post); IPHostEntry host = Dns.Resolve(uri.Host); IPAddress ip = host.AddressList [0]; Socket socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, uri.Port)); NetworkStream ns = new NetworkStream(socket, false); SslClientStream ssl = new SslClientStream(ns, uri.Host, false, protocol); ssl.ServerCertValidationDelegate += new CertificateValidationCallback(CertificateValidation); ssl.Write(bytes, 0, bytes.Length); ssl.Write(buffer, 0, buffer.Length); ssl.Flush(); StreamReader reader = new StreamReader(ssl, Encoding.UTF8); string result = reader.ReadToEnd(); int start = result.IndexOf("\r\n\r\n") + 4; start = result.IndexOf("\r\n\r\n") + 4; return(result.Substring(start)); }
public static string GetStreamPage(string url) { Uri uri = new Uri(url); if (uri.Scheme != Uri.UriSchemeHttps) { throw new NotSupportedException("Stream only works with HTTPS protocol"); } IPHostEntry host = Dns.Resolve(uri.Host); IPAddress ip = host.AddressList [0]; Socket socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, uri.Port)); NetworkStream ns = new NetworkStream(socket, false); SslClientStream ssl = new SslClientStream(ns, uri.Host, false, protocol, certificates); ssl.ServerCertValidationDelegate += new CertificateValidationCallback(CertificateValidation); StreamWriter sw = new StreamWriter(ssl); sw.WriteLine("GET {0} HTTP/1.0{1}", uri.AbsolutePath, Environment.NewLine); sw.Flush(); StreamReader sr = new StreamReader(ssl, Encoding.UTF8); return(sr.ReadToEnd()); }
static void Main(string[] args) { string host = "localhost"; if (args.Length > 0) { host = args[0]; } SecurityProtocolType protocol = SecurityProtocolType.Tls; if (args.Length > 1) { switch (args [1].ToUpper()) { case "SSL": protocol = SecurityProtocolType.Ssl3; break; } } X509CertificateCollection certificates = null; if (args.Length > 2) { string password = null; if (args.Length > 3) { password = args [3]; } p12 = Mono.Security.X509.PKCS12.LoadFromFile(args [2], password); certificates = new X509CertificateCollection(); foreach (Mono.Security.X509.X509Certificate cert in p12.Certificates) { certificates.Add(new X509Certificate(cert.RawData)); } } TcpClient client = new TcpClient(); client.Connect(host, 4433); SslClientStream ssl = new SslClientStream(client.GetStream(), host, false, protocol, certificates); ssl.ServerCertValidationDelegate += new CertificateValidationCallback(CertificateValidation); ssl.ClientCertSelectionDelegate += new CertificateSelectionCallback(ClientCertificateSelection); ssl.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback(PrivateKeySelection); StreamWriter sw = new StreamWriter(ssl, System.Text.Encoding.ASCII); sw.WriteLine("GET /clientcert.aspx{0}", Environment.NewLine); sw.Flush(); StreamReader sr = new StreamReader(ssl); Console.WriteLine(sr.ReadToEnd()); }
bool CreateStream(HttpWebRequest request) { try { NetworkStream serverStream = new NetworkStream(socket, false); if (request.Address.Scheme == Uri.UriSchemeHttps) { ssl = true; EnsureSSLStreamAvailable(); if (!reused || nstream == null || nstream.GetType() != sslStream) { byte [] buffer = null; if (sPoint.UseConnect) { bool ok = CreateTunnel(request, serverStream, out buffer); if (!ok) { return(false); } } object[] args = new object [4] { serverStream, request.ClientCertificates, request, buffer }; nstream = (Stream)Activator.CreateInstance(sslStream, args); #if SECURITY_DEP SslClientStream scs = (SslClientStream)nstream; var helper = new ServicePointManager.ChainValidationHelper(request); scs.ServerCertValidation2 += new CertificateValidationCallback2(helper.ValidateChain); #endif certsAvailable = false; } // we also need to set ServicePoint.Certificate // and ServicePoint.ClientCertificate but this can // only be done later (after handshake - which is // done only after a read operation). } else { ssl = false; nstream = serverStream; } } catch (Exception) { if (!request.Aborted) { status = WebExceptionStatus.ConnectFailure; } return(false); } return(true); }
public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols sslProtocolType, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) { if (IsAuthenticated) { throw new InvalidOperationException("This SslStream is already authenticated"); } SslClientStream s = new SslClientStream(InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol(sslProtocolType), clientCertificates); s.CheckCertRevocationStatus = checkCertificateRevocation; // Due to the Mono.Security internal, it cannot reuse // the delegated argument, as Mono.Security creates // another instance of X509Certificate which lacks // private key but is filled the private key via this // delegate. s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) { string hash = cert.GetCertHashString(); // ... so, we cannot use the delegate argument. foreach (X509Certificate cc in clientCertificates) { if (cc.GetCertHashString() != hash) { continue; } X509Certificate2 cert2 = cc as X509Certificate2; cert2 = cert2 ?? new X509Certificate2(cc); return(cert2.PrivateKey); } return(null); }; if (validation_callback != null) { s.ServerCertValidationDelegate = delegate(X509Certificate cert, int [] certErrors) { X509Chain chain = null; if (cert is X509Certificate2) { chain = new X509Chain(); chain.Build((X509Certificate2)cert); } // FIXME: SslPolicyErrors is incomplete SslPolicyErrors errors = certErrors.Length > 0 ? SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None; return(validation_callback(this, cert, chain, errors)); } } ; if (selection_callback != null) { s.ClientCertSelectionDelegate = OnCertificateSelection; } ssl_stream = s; return(BeginWrite(new byte [0], 0, 0, asyncCallback, asyncState)); }
public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) { if (IsAuthenticated) { throw new InvalidOperationException("This SslStream is already authenticated"); } SslClientStream s = new SslClientStream(InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol(enabledSslProtocols), clientCertificates); s.CheckCertRevocationStatus = checkCertificateRevocation; // Due to the Mono.Security internal, it cannot reuse // the delegated argument, as Mono.Security creates // another instance of X509Certificate which lacks // private key but is filled the private key via this // delegate. s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) { string hash = cert.GetCertHashString(); // ... so, we cannot use the delegate argument. foreach (X509Certificate cc in clientCertificates) { if (cc.GetCertHashString() != hash) { continue; } X509Certificate2 cert2 = cc as X509Certificate2; cert2 = cert2 ?? new X509Certificate2(cc); return(cert2.PrivateKey); } return(null); }; // Even if validation_callback is null this allows us to verify requests where the user // does not provide a verification callback but attempts to authenticate with the website // as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example) s.ServerCertValidation2 += (mcerts) => { X509CertificateCollection certs = null; if (mcerts != null) { certs = new X509CertificateCollection(); for (int i = 0; i < mcerts.Count; i++) { certs.Add(new X509Certificate2(mcerts [i].RawData)); } } return(((ChainValidationHelper)certificateValidator).ValidateCertificate(targetHost, false, certs)); }; s.ClientCertSelectionDelegate = OnCertificateSelection; ssl_stream = s; return(BeginWrite(new byte [0], 0, 0, asyncCallback, asyncState)); }
private void AuthAsClient() { var s = new SslClientStream(Parent.InnerStream, TargetHost, !Parent.LeaveInnerStreamOpen, GetMonoSslProtocol(EnabledProtocols), ClientCertificates) { CheckCertRevocationStatus = Options.CertificateRevocationCheckMode != X509RevocationMode.NoCheck }; // Due to the Mono.Security internal, it cannot reuse // the delegated argument, as Mono.Security creates // another instance of X509Certificate which lacks // private key but is filled the private key via this // delegate. s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) { var hash = cert.GetCertHashString(); // ... so, we cannot use the delegate argument. foreach (var cc in ClientCertificates) { if (cc.GetCertHashString() != hash) { continue; } var cert2 = cc as X509Certificate2; cert2 ??= new X509Certificate2(cc); return(cert2.PrivateKey); } return(null); }; // Even if validation_callback is null this allows us to verify requests where the user // does not provide a verification callback but attempts to authenticate with the website // as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example) s.ServerCertValidation2 += mcerts => { X509CertificateCollection certs = null; if (mcerts != null) { certs = new X509CertificateCollection(); foreach (var t in mcerts) { certs.Add(new X509Certificate2(t.RawData)); } } return(certificateValidator.ValidateCertificate(TargetHost, false, certs)); }; s.ClientCertSelectionDelegate = OnCertificateSelection; sslStream = s; }
public TlsClientSession(string host, X509Certificate2 clientCert, X509ServiceCertificateAuthentication auth) { stream = new MemoryStream(); if (clientCert == null) { ssl = new SslClientStream(stream, host, true, SecurityProtocolType.Tls); } else { ssl = new SslClientStream(stream, host, true, SecurityProtocolType.Tls, new X509CertificateCollection(new X509Certificate [] { clientCert })); mutual = true; ssl.ClientCertSelection += delegate( X509CertificateCollection clientCertificates, X509Certificate serverCertificate, string targetHost, X509CertificateCollection serverRequestedCertificates) { return(clientCertificates [0]); }; } X509CertificateValidator v = null; switch (auth.CertificateValidationMode) { case X509CertificateValidationMode.None: v = X509CertificateValidator.None; break; case X509CertificateValidationMode.PeerTrust: v = X509CertificateValidator.PeerTrust; break; case X509CertificateValidationMode.ChainTrust: v = X509CertificateValidator.ChainTrust; break; case X509CertificateValidationMode.PeerOrChainTrust: v = X509CertificateValidator.PeerOrChainTrust; break; case X509CertificateValidationMode.Custom: v = auth.CustomCertificateValidator; break; } ssl.ServerCertValidationDelegate = delegate(X509Certificate certificate, int [] certificateErrors) { v.Validate(new X509Certificate2(certificate)); // will throw SecurityTokenvalidationException if invalid. return(true); }; }
private bool CreateStream(HttpWebRequest request) { try { NetworkStream networkStream = new NetworkStream(socket, owns_socket: false); if (request.Address.Scheme == Uri.UriSchemeHttps) { ssl = true; EnsureSSLStreamAvailable(); if (!reused || nstream == null || nstream.GetType() != sslStream) { byte[] array = null; if (sPoint.UseConnect && !CreateTunnel(request, networkStream, out array)) { return(false); } object[] args = new object[4] { networkStream, request.ClientCertificates, request, array }; nstream = (Stream)Activator.CreateInstance(sslStream, args); SslClientStream sslClientStream = (SslClientStream)nstream; ServicePointManager.ChainValidationHelper @object = new ServicePointManager.ChainValidationHelper(request); sslClientStream.ServerCertValidation2 += @object.ValidateChain; certsAvailable = false; } } else { ssl = false; nstream = networkStream; } } catch (Exception) { if (!request.Aborted) { status = WebExceptionStatus.ConnectFailure; } return(false); IL_011e :; } return(true); }
private bool CreateStream(HttpWebRequest request) { try { System.Net.Sockets.NetworkStream networkStream = new System.Net.Sockets.NetworkStream(this.socket, false); if (request.Address.Scheme == System.Uri.UriSchemeHttps) { this.ssl = true; WebConnection.EnsureSSLStreamAvailable(); if (!this.reused || this.nstream == null || this.nstream.GetType() != WebConnection.sslStream) { byte[] array = null; if (this.sPoint.UseConnect && !this.CreateTunnel(request, networkStream, out array)) { return(false); } object[] args = new object[] { networkStream, request.ClientCertificates, request, array }; this.nstream = (Stream)Activator.CreateInstance(WebConnection.sslStream, args); SslClientStream sslClientStream = (SslClientStream)this.nstream; ServicePointManager.ChainValidationHelper @object = new ServicePointManager.ChainValidationHelper(request); sslClientStream.ServerCertValidation2 += @object.ValidateChain; this.certsAvailable = false; } } else { this.ssl = false; this.nstream = networkStream; } } catch (Exception) { if (!request.Aborted) { this.status = WebExceptionStatus.ConnectFailure; } return(false); } return(true); }
protected override void OnStart() { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(_server); this.InitializeNetworkStream(socket); if (this.UseTls) { SslClientStream secureStream = new SslClientStream(base.NetworkStream, "localhost", true, Mono.Security.Protocol.Tls.SecurityProtocolType.Tls); secureStream.ServerCertValidationDelegate = new CertificateValidationCallback(CertValidationCallback); base.SecureStream = secureStream; } SendMoreData(); byte[] readBuffer = new byte[ReadBufferSize]; this.BeginRead(readBuffer, 0, readBuffer.Length, new AsyncCallback(BeginReadCallback), readBuffer); }
public TlsClientSession(string host, X509Certificate2 clientCert) { stream = new MemoryStream(); if (clientCert == null) { ssl = new SslClientStream(stream, host, true, SecurityProtocolType.Tls); } else { ssl = new SslClientStream(stream, host, true, SecurityProtocolType.Tls, new X509CertificateCollection(new X509Certificate [] { clientCert })); mutual = true; ssl.ClientCertSelection += delegate( X509CertificateCollection clientCertificates, X509Certificate serverCertificate, string targetHost, X509CertificateCollection serverRequestedCertificates) { return(clientCertificates [0]); }; } }
static X509CertificateCollection GetCertificatesFromSslSession(string url) { Uri uri = new Uri(url); IPHostEntry host = Dns.Resolve(uri.Host); IPAddress ip = host.AddressList [0]; Socket socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, uri.Port)); NetworkStream ns = new NetworkStream(socket, false); SslClientStream ssl = new SslClientStream(ns, uri.Host, false, Mono.Security.Protocol.Tls.SecurityProtocolType.Default, null); ssl.ServerCertValidationDelegate += new CertificateValidationCallback(CertificateValidation); try { // we don't really want to write to the server (as we don't know // the protocol it using) but we must send something to be sure the // SSL handshake is done (so we receive the X.509 certificates). StreamWriter sw = new StreamWriter(ssl); sw.WriteLine(Environment.NewLine); sw.Flush(); socket.Poll(30000, SelectMode.SelectRead); } finally { socket.Close(); } // we need a little reflection magic to get this information PropertyInfo pi = typeof(SslStreamBase).GetProperty("ServerCertificates", BindingFlags.Instance | BindingFlags.NonPublic); if (pi == null) { Console.WriteLine("Sorry but you need a newer version of Mono.Security.dll to use this feature."); return(null); } return((X509CertificateCollection)pi.GetValue(ssl, null)); }
// make the actual connection // and HELO handshaking private void Connect() { Stream stream; if (use_ssl) { tcpConnection = new TcpClient(server, 465); stream = new SslClientStream(tcpConnection.GetStream(), server, false); } else { tcpConnection = new TcpClient(server, 25); stream = tcpConnection.GetStream(); } smtp = new EsmtpStream(stream); // read the server greeting smtp.ReadResponse(); smtp.CheckForStatusCode(220); // write the HELO command to the server smtp.WriteHelo(Dns.GetHostName()); smtp.WriteAuth(username, password); }
public override void Open(NpgsqlConnector context, Int32 timeout) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); IAsyncResult result; // Keep track of time remaining; Even though there may be multiple timeout-able calls, // this allows us to still respect the caller's timeout expectation. DateTime attemptStart; attemptStart = DateTime.Now; result = Dns.BeginGetHostAddresses(context.Host, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout, true)) { // Timeout was used up attempting the Dns lookup throw new TimeoutException(resman.GetString("Exception_DnsLookupTimeout")); } timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); IPAddress[] ips = Dns.EndGetHostAddresses(result); Socket socket = null; Exception lastSocketException = null; // try every ip address of the given hostname, use the first reachable one // make sure not to exceed the caller's timeout expectation by splitting the // time we have left between all the remaining ip's in the list. for (int i = 0; i < ips.Length; i++) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ips[i]); IPEndPoint ep = new IPEndPoint(ips[i], context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); attemptStart = DateTime.Now; try { result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(timeout / (ips.Length - i), true)) { throw new TimeoutException(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception e) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ips[i]); timeout -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds); lastSocketException = e; socket.Close(); socket = null; } } if (socket == null) { throw lastSocketException; } NpgsqlNetworkStream baseStream = new NpgsqlNetworkStream(socket, true); Stream sslStream = null; // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { baseStream .WriteInt32(8) .WriteInt32(80877103); // Receive response Char response = (Char)baseStream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); //if (context.UseMonoSsl) if (!NpgsqlConnector.UseSslStream) { SslClientStream sslStreamPriv; sslStreamPriv = new SslClientStream( baseStream, context.Host, true, SecurityProtocolType.Default, clientCertificates); sslStreamPriv.ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); sslStreamPriv.ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); sslStreamPriv.PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); sslStream = sslStreamPriv; } else { SslStream sslStreamPriv; sslStreamPriv = new SslStream(baseStream, true, context.DefaultValidateRemoteCertificateCallback); sslStreamPriv.AuthenticateAsClient(context.Host, clientCertificates, System.Security.Authentication.SslProtocols.Default, false); sslStream = sslStreamPriv; } } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Socket = socket; context.BaseStream = baseStream; context.Stream = new BufferedStream(sslStream == null ? baseStream : sslStream, 8192); NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } catch (Exception e) { throw new NpgsqlException(string.Format(resman.GetString("Exception_FailedConnection"), context.Host), e); } }
public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) { if (IsAuthenticated) { throw new InvalidOperationException("This SslStream is already authenticated"); } SslClientStream s = new SslClientStream(InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol(enabledSslProtocols), clientCertificates); s.CheckCertRevocationStatus = checkCertificateRevocation; // Due to the Mono.Security internal, it cannot reuse // the delegated argument, as Mono.Security creates // another instance of X509Certificate which lacks // private key but is filled the private key via this // delegate. s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) { string hash = cert.GetCertHashString(); // ... so, we cannot use the delegate argument. foreach (X509Certificate cc in clientCertificates) { if (cc.GetCertHashString() != hash) { continue; } X509Certificate2 cert2 = cc as X509Certificate2; cert2 = cert2 ?? new X509Certificate2(cc); return(cert2.PrivateKey); } return(null); }; if (validation_callback != null) { s.ServerCertValidationDelegate = delegate(X509Certificate cert, int [] certErrors) { X509Chain chain = new X509Chain(); X509Certificate2 x2 = (cert as X509Certificate2); if (x2 == null) { x2 = new X509Certificate2(cert); } if (!ServicePointManager.CheckCertificateRevocationList) { chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; } // SSL specific checks (done by Mono.Security.dll SSL/TLS implementation) SslPolicyErrors errors = SslPolicyErrors.None; foreach (int i in certErrors) { switch (i) { case -2146762490: // CERT_E_PURPOSE errors |= SslPolicyErrors.RemoteCertificateNotAvailable; break; case -2146762481: // CERT_E_CN_NO_MATCH errors |= SslPolicyErrors.RemoteCertificateNameMismatch; break; default: errors |= SslPolicyErrors.RemoteCertificateChainErrors; break; } } chain.Build(x2); // non-SSL specific X509 checks (i.e. RFC3280 related checks) foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.NoError) { continue; } if ((status.Status & X509ChainStatusFlags.PartialChain) != 0) { errors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { errors |= SslPolicyErrors.RemoteCertificateChainErrors; } } return(validation_callback(this, cert, chain, errors)); } } ; if (selection_callback != null) { s.ClientCertSelectionDelegate = OnCertificateSelection; } ssl_stream = s; return(BeginWrite(new byte [0], 0, 0, asyncCallback, asyncState)); }
public override void Open(NpgsqlConnector context) { try { IPAddress[] ips = ResolveIPHost(context.Host); Socket socket = null; // try every ip address of the given hostname, use the first reachable one foreach (IPAddress ip in ips) { IPEndPoint ep = new IPEndPoint(ip, context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { IAsyncResult result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout * 1000, true)) { socket.Close(); throw new Exception("Connection establishment timeout. Increase Timeout value in ConnectionString."); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception) { socket.Close(); } } if (socket == null || !socket.Connected) { throw new Exception(string.Format("Failed to establish a connection to '{0}'.", context.Host)); } Stream stream = new NpgsqlNetworkStream(context, socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char)stream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); stream = new SslClientStream( stream, context.Host, true, SecurityProtocolType.Default, clientCertificates); ((SslClientStream)stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream)stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream)stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException("Ssl connection requested. No Ssl enabled connection from this host is configured."); } } context.Stream = new NpgsqlBufferedStream(stream); context.Socket = socket; ChangeState(context, NpgsqlConnectedState.Instance); } //FIXME: Exceptions that come from what we are handling should be wrapped - e.g. an error connecting to //the server should definitely be presented to the uesr as an NpgsqlError. Exceptions from userland should //be passed untouched - e.g. ThreadAbortException because the user started this in a thread they created and //then aborted should be passed through. //Are there any others that should be pass through? Alternatively, are there a finite number that should //be wrapped? catch (ThreadAbortException) { throw; } catch (Exception e) { throw new NpgsqlException(e.Message, e); } }
public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) { if (IsAuthenticated) throw new InvalidOperationException ("This SslStream is already authenticated"); SslClientStream s = new SslClientStream (InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols), clientCertificates); s.CheckCertRevocationStatus = checkCertificateRevocation; // Due to the Mono.Security internal, it cannot reuse // the delegated argument, as Mono.Security creates // another instance of X509Certificate which lacks // private key but is filled the private key via this // delegate. s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string host) { string hash = cert.GetCertHashString (); // ... so, we cannot use the delegate argument. foreach (X509Certificate cc in clientCertificates) { if (cc.GetCertHashString () != hash) continue; X509Certificate2 cert2 = cc as X509Certificate2; cert2 = cert2 ?? new X509Certificate2 (cc); return cert2.PrivateKey; } return null; }; if (validation_callback != null) s.ServerCertValidationDelegate = delegate (X509Certificate cert, int [] certErrors) { X509Chain chain = new X509Chain (); X509Certificate2 x2 = (cert as X509Certificate2); if (x2 == null) x2 = new X509Certificate2 (cert); if (!ServicePointManager.CheckCertificateRevocationList) chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // SSL specific checks (done by Mono.Security.dll SSL/TLS implementation) SslPolicyErrors errors = SslPolicyErrors.None; foreach (int i in certErrors) { switch (i) { case -2146762490: // CERT_E_PURPOSE errors |= SslPolicyErrors.RemoteCertificateNotAvailable; break; case -2146762481: // CERT_E_CN_NO_MATCH errors |= SslPolicyErrors.RemoteCertificateNameMismatch; break; default: errors |= SslPolicyErrors.RemoteCertificateChainErrors; break; } } chain.Build (x2); // non-SSL specific X509 checks (i.e. RFC3280 related checks) foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.NoError) continue; if ((status.Status & X509ChainStatusFlags.PartialChain) != 0) errors |= SslPolicyErrors.RemoteCertificateNotAvailable; else errors |= SslPolicyErrors.RemoteCertificateChainErrors; } return validation_callback (this, cert, chain, errors); }; if (selection_callback != null) s.ClientCertSelectionDelegate = OnCertificateSelection; ssl_stream = s; return BeginWrite (new byte [0], 0, 0, asyncCallback, asyncState); }
public virtual IAsyncResult BeginAuthenticateAsClient( string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState) { if (this.IsAuthenticated) { throw new InvalidOperationException("This SslStreamM is already authenticated"); } SslClientStream sslClientStream = new SslClientStream(this.InnerStream, targetHost, !this.LeaveInnerStreamOpen, this.GetMonoSslProtocol(enabledSslProtocols), clientCertificates); sslClientStream.CheckCertRevocationStatus = checkCertificateRevocation; sslClientStream.PrivateKeyCertSelectionDelegate = (PrivateKeySelectionCallback)((cert, host) => { string certHashString = cert.GetCertHashString(); foreach (X509Certificate clientCertificate in clientCertificates) { if (!(clientCertificate.GetCertHashString() != certHashString)) { if (!(clientCertificate is X509Certificate2 x509Certificate2)) { x509Certificate2 = new X509Certificate2(clientCertificate); } return(x509Certificate2.PrivateKey); } } return((AsymmetricAlgorithm)null); }); if (this.validation_callback != null) { sslClientStream.ServerCertValidationDelegate = (CertificateValidationCallback)((cert, certErrors) => { X509Chain chain = new X509Chain(); if (!(cert is X509Certificate2 certificate)) { certificate = new X509Certificate2(cert); } if (!ServicePointManager.CheckCertificateRevocationList) { chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; } SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; foreach (int certError in certErrors) { switch (certError) { case -2146762490: sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; break; case -2146762481: sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch; break; default: sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; break; } } chain.Build(certificate); foreach (X509ChainStatus chainStatu in chain.ChainStatus) { if (chainStatu.Status != X509ChainStatusFlags.NoError) { if ((chainStatu.Status & X509ChainStatusFlags.PartialChain) != X509ChainStatusFlags.NoError) { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable; } else { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } } } return(this.validation_callback((object)this, cert, chain, sslPolicyErrors)); }); } if (this.selection_callback != null) { sslClientStream.ClientCertSelectionDelegate = new CertificateSelectionCallback(this.OnCertificateSelection); } this.ssl_stream = (SslStreamBase)sslClientStream; return(this.BeginWrite(new byte[0], 0, 0, asyncCallback, asyncState)); }
public static void Main(string[] args) { if (args.Length == 0) { Usage("Missing arguments"); return; } ArrayList urls = new ArrayList(); foreach (string arg in args) { switch (arg) { // protocol case "--any": protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Default; break; case "--ssl": case "--ssl3": protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Ssl3; break; case "--tls": case "--tls1": protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Tls; break; // options case "--time": time = true; break; case "--show": show = true; break; case "--help": Usage(null); return; // credentials, certificates, urls or bad options default: if (arg.StartsWith("--read:")) { string rval = arg.Substring(7); if (rval == "loop") { readloop = true; } else { read = Int32.Parse(rval); } continue; } else if (arg.StartsWith("--write:")) { string wval = arg.Substring(8); if (wval == "loop") { writeloop = true; } else { write = Int32.Parse(wval); } continue; } else if (arg.StartsWith("--")) { Usage("Invalid option " + arg); return; } urls.Add(arg); break; } } if (readloop && writeloop) { Usage("Can't loop on both read and write"); return; } int loop = 1; if (readloop || writeloop) { // this is it meant to be stopped manually loop = Int32.MaxValue; } if (urls.Count == 0) { Usage("no URL were specified"); return; } for (int i = 0; i < loop; i++) { if (readloop || writeloop) { Console.WriteLine("*** LOOP {0} ***", i); } foreach (string url in urls) { Console.WriteLine("{0}{1}", Environment.NewLine, url); string content = null; DateTime start = DateTime.Now; Uri uri = new Uri(url); if (uri.Scheme != Uri.UriSchemeHttps) { throw new NotSupportedException("Stream only works with HTTPS protocol"); } ControlledNetworkStream ns = null; try { IPHostEntry host = Dns.Resolve(uri.Host); IPAddress ip = host.AddressList [0]; Socket socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(ip, uri.Port)); ns = new ControlledNetworkStream(socket, false); ns.MaximumRead = (readloop) ? i : read; ns.MaximumWrite = (writeloop) ? i : write; SslClientStream ssl = new SslClientStream(ns, uri.Host, false, protocol); ssl.ServerCertValidationDelegate += new CertificateValidationCallback(CertificateValidation); StreamWriter sw = new StreamWriter(ssl); sw.WriteLine("GET {0}{1}", uri.AbsolutePath, Environment.NewLine); sw.Flush(); StreamReader sr = new StreamReader(ssl, Encoding.UTF8); content = sr.ReadToEnd(); } catch (Exception e) { // HResult is protected - but very useful in debugging PropertyInfo pi = e.GetType().GetProperty("HResult", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); Console.WriteLine("FAILED: #{0}", (int)pi.GetValue(e, null)); Console.WriteLine(e.ToString()); if (ns != null) { Console.WriteLine("Bytes Read: {0}", ns.CurrentRead); Console.WriteLine("Max Read: {0}", ns.MaximumRead); Console.WriteLine("Bytes Write: {0}", ns.CurrentWrite); Console.WriteLine("Max Write: {0}", ns.MaximumWrite); } } TimeSpan ts = (DateTime.Now - start); if ((show) && (content != null)) { Console.WriteLine("{0}{1}{0}", Environment.NewLine, content); } if (time) { Console.WriteLine("Time: " + ts.ToString()); } } } }
public override void Open(NpgsqlConnector context) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); /*TcpClient tcpc = new TcpClient(); * tcpc.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); * Stream stream = tcpc.GetStream();*/ /*socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendTimeout, context.ConnectionTimeout*1000);*/ //socket.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); /*Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); * * IAsyncResult result = socket.BeginConnect(new IPEndPoint(ResolveIPHost(context.Host), context.Port), null, null); * * if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout*1000, false)) * { * socket.Close(); * throw new Exception(resman.GetString("Exception_ConnectionTimeout")); * } * * try * { * socket.EndConnect(result); * } * catch (Exception) * { * socket.Close(); * throw; * } */ IPAddress[] ips = ResolveIPHost(context.Host); Socket socket = null; // try every ip address of the given hostname, use the first reachable one foreach (IPAddress ip in ips) { NpgsqlEventLog.LogMsg(resman, "Log_ConnectingTo", LogLevel.Debug, ip); IPEndPoint ep = new IPEndPoint(ip, context.Port); socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { IAsyncResult result = socket.BeginConnect(ep, null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout * 1000, true)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } socket.EndConnect(result); // connect was successful, leave the loop break; } catch (Exception) { NpgsqlEventLog.LogMsg(resman, "Log_FailedConnection", LogLevel.Normal, ip); socket.Close(); } } if (socket == null || !socket.Connected) { throw new Exception(string.Format(resman.GetString("Exception_FailedConnection"), context.Host)); } //Stream stream = new NetworkStream(socket, true); Stream stream = new NpgsqlNetworkStream(context, socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char)stream.ReadByte(); if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); stream = new SslClientStream( stream, context.Host, true, SecurityProtocolType.Default, clientCertificates); ((SslClientStream)stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream)stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream)stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Stream = new BufferedStream(stream); context.Socket = socket; NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } //FIXME: Exceptions that come from what we are handling should be wrapped - e.g. an error connecting to //the server should definitely be presented to the uesr as an NpgsqlError. Exceptions from userland should //be passed untouched - e.g. ThreadAbortException because the user started this in a thread they created and //then aborted should be passed through. //Are there any others that should be pass through? Alternatively, are there a finite number that should //be wrapped? catch (ThreadAbortException) { throw; } catch (Exception e) { throw new NpgsqlException(e.Message, e); } }
public override void Open(NpgsqlConnector context) { try { NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open"); /*TcpClient tcpc = new TcpClient(); * tcpc.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); * Stream stream = tcpc.GetStream();*/ Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); /*socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendTimeout, context.ConnectionTimeout*1000);*/ //socket.Connect(new IPEndPoint(ResolveIPHost(context.Host), context.Port)); IAsyncResult result = socket.BeginConnect(new IPEndPoint(ResolveIPHost(context.Host), context.Port), null, null); if (!result.AsyncWaitHandle.WaitOne(context.ConnectionTimeout * 1000, true)) { socket.Close(); throw new Exception(resman.GetString("Exception_ConnectionTimeout")); } try { socket.EndConnect(result); } catch (Exception ex) { socket.Close(); throw; } Stream stream = new NetworkStream(socket, true); // If the PostgreSQL server has SSL connectors enabled Open SslClientStream if (response == 'S') { if (context.SSL || (context.SslMode == SslMode.Require) || (context.SslMode == SslMode.Prefer)) { PGUtil.WriteInt32(stream, 8); PGUtil.WriteInt32(stream, 80877103); // Receive response Char response = (Char)stream.ReadByte(); if (response == 'S') { stream = new SslClientStream( stream, context.Host, true, Mono.Security.Protocol.Tls.SecurityProtocolType.Default ); ((SslClientStream)stream).ClientCertSelectionDelegate = new CertificateSelectionCallback(context.DefaultCertificateSelectionCallback); ((SslClientStream)stream).ServerCertValidationDelegate = new CertificateValidationCallback(context.DefaultCertificateValidationCallback); ((SslClientStream)stream).PrivateKeyCertSelectionDelegate = new PrivateKeySelectionCallback(context.DefaultPrivateKeySelectionCallback); } else if (context.SslMode == SslMode.Require) { throw new InvalidOperationException(resman.GetString("Exception_Ssl_RequestError")); } } context.Stream = new BufferedStream(stream); context.Socket = socket; NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.Host, context.Port); ChangeState(context, NpgsqlConnectedState.Instance); } catch (Exception e) { throw new NpgsqlException(e.Message, e); } }