public AuthenticateAsClientAsync ( string targetHost ) : System.Threading.Tasks.Task | ||
targetHost | string | |
return | System.Threading.Tasks.Task |
/// <summary> /// Initializes a client instance of <see cref="DesktopNetworkStream"/>. /// </summary> /// <param name="host">Network host.</param> /// <param name="port">Network port.</param> /// <param name="useTls">Use TLS layer?</param> /// <param name="noDelay">No delay?</param> /// <param name="ignoreSslPolicyErrors">Ignore SSL policy errors?</param> internal DesktopNetworkStream(string host, int port, bool useTls, bool noDelay, bool ignoreSslPolicyErrors) { this.Host = host; this.Port = port; #if NETSTANDARD this.tcpClient = new TcpClient { NoDelay = noDelay }; this.tcpClient.ConnectAsync(host, port).Wait(); #else this.tcpClient = new TcpClient(host, port) { NoDelay = noDelay }; #endif Stream stream = this.tcpClient.GetStream(); if (useTls) { var ssl = new SslStream( stream, false, (sender, certificate, chain, errors) => errors == SslPolicyErrors.None || ignoreSslPolicyErrors); #if NETSTANDARD ssl.AuthenticateAsClientAsync(host).Wait(); #else ssl.AuthenticateAsClient(host); #endif stream = ssl; } this.networkStream = stream; }
public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint) { try { using (var client = CreateConnectedTcpClient(serviceEndpoint)) { using (var stream = client.GetStream()) { using (var ssl = new SslStream(stream, false, ValidateCertificate)) { ssl.AuthenticateAsClientAsync(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false) .GetAwaiter() .GetResult(); ssl.Write(HelloLine, 0, HelloLine.Length); ssl.Flush(); if (ssl.RemoteCertificate == null) throw new Exception("The server did not provide an SSL certificate"); return new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint); } } } } catch (Exception ex) { throw new HalibutClientException(ex.Message, ex); } }
public override Task PostEmailAsync(string name, string[] to, string[] cc, string[] bcc, string subject, string message, params Attachment[] Attachments) { if (!ssl) return Task.Factory.StartNew(async () => { using (var client = new TcpClient()) { await client.ConnectAsync(server, port); using (var stream = client.GetStream()) using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream) { AutoFlush = true, NewLine = "\r\n" }) { TcpWrite(writer, reader, name, to, cc, bcc, subject, message, Attachments); } } }); else return Task.Factory.StartNew(async () => { using (var client = new TcpClient()) { await client.ConnectAsync(server, port); using (var stream = new SslStream(client.GetStream(), false)) { await stream.AuthenticateAsClientAsync(server); using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream) { AutoFlush = true, NewLine = "\r\n" }) { TcpWrite(writer, reader, name, to, cc, bcc, subject, message, Attachments); } } } }); }
public async Task<Stream> ConnectAsync(string host, int port, X509Certificate clientCert, CancellationToken cancel) { Stream lowerStream = null; SslStream sslStream = null; X509CertificateCollection certCollection = null;; if (clientCert != null) { certCollection = new X509CertificateCollection(new[] { clientCert }); } try { lowerStream = await _connectionResolver.ConnectAsync(host, port, cancel); sslStream = new SslStream(lowerStream); await sslStream.AuthenticateAsClientAsync(host, certCollection, _protocols, checkCertificateRevocation: true); return sslStream; } catch (Exception) { if (sslStream != null) { sslStream.Dispose(); } if (lowerStream != null) { lowerStream.Dispose(); } throw; } }
public static void Main(string[] args) { Console.WriteLine("Starting..."); X509Certificate2 serverCertificate = new X509Certificate2("certificate.pfx"); // Any valid certificate with private key will work fine. TcpListener listener = new TcpListener(IPAddress.Any, 4567); TcpClient client = new TcpClient(); listener.Start(); Task clientConnectTask = client.ConnectAsync(IPAddress.Loopback, 4567); Task<TcpClient> listenerAcceptTask = listener.AcceptTcpClientAsync(); Task.WaitAll(clientConnectTask, listenerAcceptTask); TcpClient server = listenerAcceptTask.Result; SslStream clientStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null, EncryptionPolicy.RequireEncryption); SslStream serverStream = new SslStream(server.GetStream(), false, null, null, EncryptionPolicy.RequireEncryption); Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync(serverCertificate.GetNameInfo(X509NameType.SimpleName, false), null, SslProtocols.Tls12, false); Task serverAuthenticationTask = serverStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.Tls12, false); Task.WaitAll(clientAuthenticationTask, serverAuthenticationTask); byte[] readBuffer = new byte[256]; Task<int> readTask = clientStream.ReadAsync(readBuffer, 0, readBuffer.Length); // Create a pending ReadAsync, which will wait for data that will never come (for testing purposes). byte[] writeBuffer = new byte[256]; Task writeTask = clientStream.WriteAsync(writeBuffer, 0, writeBuffer.Length); // The main thread actually blocks here (not asychronously waits) on .NET Core making this call. bool result = Task.WaitAll(new Task[1] { writeTask }, 5000); // This code won't even be reached on .NET Core. Works fine on .NET Framework. if (result) { Console.WriteLine("WriteAsync completed successfully while ReadAsync was pending... nothing locked up."); } else { Console.WriteLine("WriteAsync failed to complete after 5 seconds."); } }
async protected override Task InitRemoteStream() { await base.InitRemoteStream(); var secureRemoteStream = new SslStream(RemoteStream, true, RemoteCertificateValidator); var targetHost = WrapperRequest.Prologue.Headers.First(x => x.Key == "Host").Value; await secureRemoteStream.AuthenticateAsClientAsync(targetHost); SecureRemoteStream = secureRemoteStream; }
public async Task Connect () { if (IsConnected ()) return; tcp = new TcpClient (); // Disable Nagle for HTTP/2 tcp.NoDelay = true; await tcp.ConnectAsync (Host, (int)Port); if (UseTls) { sslStream = new SslStream (tcp.GetStream (), false, (sender, certificate, chain, sslPolicyErrors) => true); await sslStream.AuthenticateAsClientAsync ( Host, Certificates ?? new X509CertificateCollection (), System.Security.Authentication.SslProtocols.Tls12, false); clientStream = sslStream; } else { clientStream = tcp.GetStream (); } // Send out preface data var prefaceData = System.Text.Encoding.ASCII.GetBytes (ConnectionPreface); await clientStream.WriteAsync (prefaceData, 0, prefaceData.Length); await clientStream.FlushAsync (); // Start reading the stream on another thread var readTask = Task.Factory.StartNew (() => { try { read (); } catch (Exception ex) { Console.WriteLine ("Read error: " + ex); Disconnect (); } }, TaskCreationOptions.LongRunning); readTask.ContinueWith (t => { // TODO: Handle the error Console.WriteLine ("Error: " + t.Exception); Disconnect (); }, TaskContinuationOptions.OnlyOnFaulted); // Send an un-ACK'd settings frame await SendFrame(new SettingsFrame ()); // We need to wait for settings server preface to come back now resetEventConnectionSettingsFrame = new ManualResetEventSlim (); resetEventConnectionSettingsFrame.Reset (); if (!resetEventConnectionSettingsFrame.Wait (ConnectionTimeout)) { Disconnect (); throw new Exception ("Connection timed out"); } }
protected override Stream createClientStream(string host, int port) { var rval = new SslStream(base.createClientStream(host, port), false, (o, cert, chain, errors) => true); //rval.AuthenticateAsClient(host); Task task = rval.AuthenticateAsClientAsync(host); task.Wait(); return rval; }
/// <summary> /// Establishes a TCP connection with the endpoint at the specified address/port pair. /// </summary> /// <param name="address">The address of the endpoint to connect to.</param> /// <param name="port">The port of the endpoint to connect to.</param> /// <param name="secure">True to enable TLS on the socket.</param> public async Task ConnectAsync(string address, int port, bool secure = false) { await _backingTcpClient.ConnectAsync(address, port); InitializeWriteStream(); if (secure) { var secureStream = new SslStream(_writeStream, true, (sender, cert, chain, sslPolicy) => ServerValidationCallback(sender, cert, chain, sslPolicy)); await secureStream.AuthenticateAsClientAsync(address, null, System.Security.Authentication.SslProtocols.Tls, false); _secureStream = secureStream; } }
} // proc OnRunJob private async Task OnRunJobAsync() { inConnectionPhase = true; try { var timeoutSource = new CancellationTokenSource(30000); // resolve end point var serverTcp = this.GetService<IServerTcp>(true); if (endPoint == null) endPoint = await serverTcp.ResolveEndpointAsync(targetHost, targetPort, timeoutSource.Token); // register the connection if (endPoint != null) { var protocol = this.GetService<OdetteFileTransferProtocolItem>(true); // check if the protocol is running if (protocol.IsActiveProtocol(ChannelName)) Log.Info("Protocol is already active."); else // create the connection try { var stream = await serverTcp.CreateConnectionAsync(endPoint, timeoutSource.Token); if (useSsl) { var ssl = new SslStream(stream, false, SslRemoteCertificateValidateCallback); // , SslLocalCertificateSelector await ssl.AuthenticateAsClientAsync(targetHost); var cert = ssl.RemoteCertificate; Log.Info($"Ssl active: auth={ssl.IsAuthenticated}, encrypt={ssl.IsEncrypted}, signed={ssl.IsSigned}\nissuer={cert.Issuer}\nsubject={cert.Subject}"); stream = ssl; } await protocol.StartProtocolAsync(new OdetteNetworkStream(stream, channelName, Config), true); } catch (Exception e) { Log.Except("Connection failed.", e); } } } catch (Exception e) { Log.Except(e); } finally { inConnectionPhase = false; } } // proc OnRunJobAsync
private async Task<Stream> CreateStream(Uri uri, Socket socket) { Stream stream = new NetworkStream(socket); if (uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) { var sslStream = new SslStream(stream); await sslStream.AuthenticateAsClientAsync(uri.Host, new X509CertificateCollection(), _sslProtocols, checkCertificateRevocation: false); stream = sslStream; } return stream; }
public async Task<ConnectStatus> ConnectTls () { try { SslStream ssl = new SslStream(tcpc.GetStream(), false, CertificateValidationCallBack); await ssl.AuthenticateAsClientAsync(host); stream = ssl; return ConnectStatus.Ok; } catch { return ConnectStatus.Failed; } }
async Task<Stream> IConnectionFactory.Connect(string hostname, int port, bool useSsl) { TcpClient client = new TcpClient(); client.NoDelay = true; await client.ConnectAsync(hostname, port); if (useSsl) { SslStream sslStream = new SslStream(client.GetStream()); await sslStream.AuthenticateAsClientAsync(hostname); return sslStream; } return client.GetStream(); }
protected override async Task<Stream> GetNetworkStream(TcpClient client) { var sslStream = new SslStream( client.GetStream(), false, ValidateServerCertificate, null ); await sslStream.AuthenticateAsClientAsync(Hostname).ConfigureAwait(false); return sslStream; }
private async Task Connect() { try { // Could be a reconnect - get rid of the old stream if so if (_stream != null) { _stream.Dispose(); _stream = null; } await _tcpClient.ConnectAsync(_host, _port); _stream = _tcpClient.GetStream(); _stream.ReadTimeout = _configuration.WaitForDataTimeoutInMilliseconds; if (_configuration.Ssl) { var sslStream = new SslStream(_stream, false, _configuration.CertificateValidationCallback); await sslStream.AuthenticateAsClientAsync(_host); _stream = sslStream; } if (_configuration.Password != null) { var response = await Command.From("AUTH", _configuration.Password).SendAsync(this); if (response.Value.IsError || response.Value.ToString() != "OK") throw ExceptionBecause.Connection.FailedToAuthenticate(response); } _configuration.Events.OnConnectionOpened(new ConnectionEventArgs { Host = _host, Port = _port }); } catch (Exception e) { _configuration.Events.OnConnectionError(new ConnectionEventArgs { Host = _host, Port = _port, Exception = e }); throw; } }
public async Task<Stream> GetStreamAsync(Socket socket, HttpRequestMessage request) { Stream networkStream = new NetworkStream(socket); if (request.RequestUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) { var httpsStream = new SslStream(networkStream); await httpsStream.AuthenticateAsClientAsync(request.RequestUri.DnsSafeHost); networkStream = httpsStream; } return networkStream; }
public async Task Connect(string Server, int Port) { try { TCPClient.Connect(Server, Port); SSLStream = new SslStream(TCPClient.GetStream(), false, (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { return true; }) { ReadTimeout = 50000, WriteTimeout = 50000 }; await SSLStream.AuthenticateAsClientAsync(Server); } catch { } }
private async Task<SslStream> GetStream() { await streamSemaphore.WaitAsync(); try { if(stream!=null) return stream; var tcpClient = new TcpClient(); await tcpClient.ConnectAsync(Host, Port); stream = new SslStream(tcpClient.GetStream(), false, (source, cert, chain, policy) => { return Fingerprint==null || Fingerprint.Equals(cert.GetCertHashString(), StringComparison.OrdinalIgnoreCase); }); await stream.AuthenticateAsClientAsync("", new X509CertificateCollection(), SslProtocols.Tls, true); DrainStream(stream); return stream; } finally { streamSemaphore.Release(); } }
public async Task ConnectAsync(Address address, ConnectionFactory factory) { Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); if (factory.tcpSettings != null) { factory.tcpSettings.Configure(socket); } await Task.Factory.FromAsync( (c, s) => ((Socket)s).BeginConnect(address.Host, address.Port, c, s), (r) => ((Socket)r.AsyncState).EndConnect(r), socket); IAsyncTransport transport; if (address.UseSsl) { SslStream sslStream; var ssl = factory.SslInternal; if (ssl == null) { sslStream = new SslStream(new NetworkStream(socket)); await sslStream.AuthenticateAsClientAsync(address.Host); } else { sslStream = new SslStream(new NetworkStream(socket), false, ssl.RemoteCertificateValidationCallback, ssl.LocalCertificateSelectionCallback); await sslStream.AuthenticateAsClientAsync(address.Host, ssl.ClientCertificates, ssl.Protocols, ssl.CheckCertificateRevocation); } transport = new SslSocket(this, sslStream); } else { transport = new TcpSocket(this, socket); } this.socketTransport = transport; this.writer = new Writer(this, this.socketTransport); }
public async Task<Stream> CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken) { var stream = await _wrapped.CreateStreamAsync(endPoint, cancellationToken).ConfigureAwait(false); var sslStream = new SslStream( stream, leaveInnerStreamOpen: false, userCertificateValidationCallback: _settings.ServerCertificateValidationCallback, userCertificateSelectionCallback: _settings.ClientCertificateSelectionCallback); string targetHost; DnsEndPoint dnsEndPoint; IPEndPoint ipEndPoint; if ((dnsEndPoint = endPoint as DnsEndPoint) != null) { targetHost = dnsEndPoint.Host; } else if ((ipEndPoint = endPoint as IPEndPoint) != null) { targetHost = ipEndPoint.Address.ToString(); } else { targetHost = endPoint.ToString(); } var clientCertificates = new X509CertificateCollection(_settings.ClientCertificates.ToArray()); try { await sslStream.AuthenticateAsClientAsync(targetHost, clientCertificates, _settings.EnabledSslProtocols, _settings.CheckCertificateRevocation).ConfigureAwait(false); } catch { stream.Close(); stream.Dispose(); throw; } return sslStream; }
public async Task<EndpointStatus> GetStatus() { try { var socket = await ConnectSocket().ConfigureAwait(false); if (socket == null) { return new EndpointStatus(false, _endpoint); } socket.SendTimeout = _timeoutMilliseconds; socket.ReceiveTimeout = _timeoutMilliseconds; EndpointStatus endpointStatus; using (var networkStream = new NetworkStream(socket, true)) { Stream stream = networkStream; if (_isHttps) { var sslStream = new SslStream(networkStream); await sslStream.AuthenticateAsClientAsync(_server).ConfigureAwait(false); stream = sslStream; } endpointStatus = await GetStatus(stream).ConfigureAwait(false); } return endpointStatus; } catch { return new EndpointStatus(false, _endpoint); } }
public async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) { // TODO: Not currently implemented: // - ClientWebSocketOptions.Credentials // - ClientWebSocketOptions.Proxy // Establish connection to the server CancellationTokenRegistration registration = cancellationToken.Register(s => ((WebSocketHandle)s).Abort(), this); try { // Connect to the remote server Socket connectedSocket = await ConnectSocketAsync(uri.Host, uri.Port, cancellationToken).ConfigureAwait(false); Stream stream = new AsyncEventArgsNetworkStream(connectedSocket); // Upgrade to SSL if needed if (uri.Scheme == UriScheme.Wss) { var sslStream = new SslStream(stream); await sslStream.AuthenticateAsClientAsync( uri.Host, options.ClientCertificates, SecurityProtocol.AllowedSecurityProtocols, checkCertificateRevocation: false).ConfigureAwait(false); stream = sslStream; } // Create the security key and expected response, then build all of the request headers KeyValuePair<string, string> secKeyAndSecWebSocketAccept = CreateSecKeyAndSecWebSocketAccept(); byte[] requestHeader = BuildRequestHeader(uri, options, secKeyAndSecWebSocketAccept.Key); // Write out the header to the connection await stream.WriteAsync(requestHeader, 0, requestHeader.Length, cancellationToken).ConfigureAwait(false); // Parse the response and store our state for the remainder of the connection string subprotocol = await ParseAndValidateConnectResponseAsync(stream, options, secKeyAndSecWebSocketAccept.Value, cancellationToken).ConfigureAwait(false); _webSocket = ManagedWebSocket.CreateFromConnectedStream(stream, false, subprotocol); // If a concurrent Abort or Dispose came in before we set _webSocket, make sure to update it appropriately if (_state == WebSocketState.Aborted) { _webSocket.Abort(); } else if (_state == WebSocketState.Closed) { _webSocket.Dispose(); } } catch (Exception exc) { if (_state < WebSocketState.Closed) { _state = WebSocketState.Closed; } Abort(); if (exc is WebSocketException) { throw; } throw new WebSocketException(SR.net_webstatus_ConnectFailure, exc); } finally { registration.Dispose(); } }
public async Task CertificatePassedToHttpContext() { RemoteCertificateValidationCallback validationCallback = (sender, cert, chain, sslPolicyErrors) => true; try { #if DNX451 ServicePointManager.ServerCertificateValidationCallback += validationCallback; #endif var serverAddress = "https://*****:*****@"TestResources/testCert.pfx", "testPassword"), ClientCertificateMode = ClientCertificateMode.RequireCertificate, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true }, new NoOpConnectionFilter()) }; RequestDelegate app = context => { var tlsFeature = context.Features.Get<ITlsConnectionFeature>(); Assert.NotNull(tlsFeature); Assert.NotNull(tlsFeature.ClientCertificate); Assert.NotNull(context.Connection.ClientCertificate); return context.Response.WriteAsync("hello world"); }; using (var server = new TestServer(app, serviceContext, serverAddress)) { // SslStream is used to ensure the certificate is actually passed to the server // HttpClient might not send the certificate because it is invalid or it doesn't match any // of the certificate authorities sent by the server in the SSL handshake. using (var client = new TcpClient()) { await client.ConnectAsync("127.0.0.1", 54321); SslStream stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true, (sender, host, certificates, certificate, issuers) => new X509Certificate2(@"TestResources/testCert.pfx", "testPassword")); await stream.AuthenticateAsClientAsync("localhost"); var request = Encoding.UTF8.GetBytes("GET / HTTP/1.0\r\n\r\n"); await stream.WriteAsync(request, 0, request.Length); var reader = new StreamReader(stream); var line = await reader.ReadLineAsync(); Assert.Equal("HTTP/1.0 200 OK", line); } } } finally { #if DNX451 ServicePointManager.ServerCertificateValidationCallback -= validationCallback; #endif } }
/// <summary> /// Establishes a connection to the specified SMTP or SMTP/S server. /// </summary> /// <remarks> /// <para>Establishes a connection to the specified SMTP or SMTP/S server.</para> /// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the /// <paramref name="options"/> parameter is used to determine the default port to /// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/> /// is <c>465</c>. All other values will use a default port of <c>25</c>.</para> /// <para>If the <paramref name="options"/> has a value of /// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used /// to determine the default security options. If the <paramref name="port"/> has a value /// of <c>465</c>, then the default options used will be /// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use /// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para> /// <para>Once a connection is established, properties such as /// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be /// populated.</para> /// <note type="note">The connection established by any of the /// <a href="Overload_MailKit_Net_Smtp_SmtpClient_Connect.htm">Connect</a> /// methods may be re-used if an application wishes to send multiple messages /// to the same SMTP server. Since connecting and authenticating can be expensive /// operations, re-using a connection can significantly improve performance when /// sending a large number of messages to the same SMTP server over a short /// period of time.</note> /// </remarks> /// <example> /// <code language="c#" source="Examples\SmtpExamples.cs" region="SendMessage"/> /// </example> /// <param name="host">The host name to connect to.</param> /// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param> /// <param name="options">The secure socket options to when connecting.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="host"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// The <paramref name="host"/> is a zero-length string. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="SmtpClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The <see cref="SmtpClient"/> is already connected. /// </exception> /// <exception cref="System.NotSupportedException"> /// <paramref name="options"/> was set to /// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/> /// and the SMTP server does not support the STARTTLS extension. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled. /// </exception> /// <exception cref="System.Net.Sockets.SocketException"> /// A socket error occurred trying to connect to the remote host. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="SmtpCommandException"> /// An SMTP command failed. /// </exception> /// <exception cref="SmtpProtocolException"> /// An SMTP protocol error occurred. /// </exception> public override void Connect (string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken)) { if (host == null) throw new ArgumentNullException (nameof (host)); if (host.Length == 0) throw new ArgumentException ("The host name cannot be empty.", nameof (host)); if (port < 0 || port > 65535) throw new ArgumentOutOfRangeException (nameof (port)); CheckDisposed (); if (IsConnected) throw new InvalidOperationException ("The SmtpClient is already connected."); capabilities = SmtpCapabilities.None; AuthenticationMechanisms.Clear (); MaxSize = 0; SmtpResponse response; Stream stream; bool starttls; Uri uri; ComputeDefaultValues (host, ref port, ref options, out uri, out starttls); #if !NETFX_CORE #if COREFX var ipAddresses = Dns.GetHostAddressesAsync (uri.DnsSafeHost).GetAwaiter ().GetResult (); #else var ipAddresses = Dns.GetHostAddresses (uri.DnsSafeHost); #endif Socket socket = null; for (int i = 0; i < ipAddresses.Length; i++) { socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = timeout, SendTimeout = timeout }; try { cancellationToken.ThrowIfCancellationRequested (); if (LocalEndPoint != null) socket.Bind (LocalEndPoint); socket.Connect (ipAddresses[i], port); break; } catch (OperationCanceledException) { socket.Dispose (); socket = null; throw; } catch { socket.Dispose (); socket = null; if (i + 1 == ipAddresses.Length) throw; } } if (socket == null) throw new IOException (string.Format ("Failed to resolve host: {0}", host)); this.host = host; if (options == SecureSocketOptions.SslOnConnect) { var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate); try { #if COREFX ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult (); #else ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true); #endif } catch { ssl.Dispose (); throw; } secure = true; stream = ssl; } else { stream = new NetworkStream (socket, true); secure = false; } #else var protection = options == SecureSocketOptions.SslOnConnect ? SocketProtectionLevel.Tls12 : SocketProtectionLevel.PlainSocket; var socket = new StreamSocket (); try { cancellationToken.ThrowIfCancellationRequested (); socket.ConnectAsync (new HostName (host), port.ToString (), protection) .AsTask (cancellationToken) .GetAwaiter () .GetResult (); } catch { socket.Dispose (); throw; } stream = new DuplexStream (socket.InputStream.AsStreamForRead (0), socket.OutputStream.AsStreamForWrite (0)); secure = options == SecureSocketOptions.SslOnConnect; this.host = host; #endif if (stream.CanTimeout) { stream.WriteTimeout = timeout; stream.ReadTimeout = timeout; } ProtocolLogger.LogConnect (uri); Stream = new SmtpStream (stream, socket, ProtocolLogger); try { // read the greeting response = Stream.ReadResponse (cancellationToken); if (response.StatusCode != SmtpStatusCode.ServiceReady) throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response); // Send EHLO and get a list of supported extensions Ehlo (cancellationToken); if (options == SecureSocketOptions.StartTls && (capabilities & SmtpCapabilities.StartTLS) == 0) throw new NotSupportedException ("The SMTP server does not support the STARTTLS extension."); if (starttls && (capabilities & SmtpCapabilities.StartTLS) != 0) { response = SendCommand ("STARTTLS", cancellationToken); if (response.StatusCode != SmtpStatusCode.ServiceReady) throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response); #if !NETFX_CORE var tls = new SslStream (stream, false, ValidateRemoteCertificate); #if COREFX tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult (); #else tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true); #endif Stream.Stream = tls; #else socket.UpgradeToSslAsync (SocketProtectionLevel.Tls12, new HostName (host)) .AsTask (cancellationToken) .GetAwaiter () .GetResult (); #endif secure = true; // Send EHLO again and get the new list of supported extensions Ehlo (cancellationToken); } connected = true; } catch { Stream.Dispose (); secure = false; Stream = null; throw; } OnConnected (); }
/// <summary> /// Establish a connection to the specified SMTP or SMTP/S server using the provided socket. /// </summary> /// <remarks> /// <para>Establishes a connection to the specified SMTP or SMTP/S server.</para> /// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the /// <paramref name="options"/> parameter is used to determine the default port to /// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/> /// is <c>465</c>. All other values will use a default port of <c>25</c>.</para> /// <para>If the <paramref name="options"/> has a value of /// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used /// to determine the default security options. If the <paramref name="port"/> has a value /// of <c>465</c>, then the default options used will be /// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use /// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para> /// <para>Once a connection is established, properties such as /// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be /// populated.</para> /// <note type="note">The connection established by any of the /// <a href="Overload_MailKit_Net_Smtp_SmtpClient_Connect.htm">Connect</a> /// methods may be re-used if an application wishes to send multiple messages /// to the same SMTP server. Since connecting and authenticating can be expensive /// operations, re-using a connection can significantly improve performance when /// sending a large number of messages to the same SMTP server over a short /// period of time./</note> /// </remarks> /// <param name="socket">The socket to use for the connection.</param> /// <param name="host">The host name to connect to.</param> /// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param> /// <param name="options">The secure socket options to when connecting.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="socket"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="host"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <para><paramref name="socket"/> is not connected.</para> /// <para>-or-</para> /// The <paramref name="host"/> is a zero-length string. /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="SmtpClient"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The <see cref="SmtpClient"/> is already connected. /// </exception> /// <exception cref="System.NotSupportedException"> /// <paramref name="options"/> was set to /// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/> /// and the SMTP server does not support the STARTTLS extension. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="SmtpCommandException"> /// An SMTP command failed. /// </exception> /// <exception cref="SmtpProtocolException"> /// An SMTP protocol error occurred. /// </exception> public void Connect (Socket socket, string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken)) { if (socket == null) throw new ArgumentNullException (nameof (socket)); if (!socket.Connected) throw new ArgumentException ("The socket is not connected.", nameof (socket)); if (host == null) throw new ArgumentNullException (nameof (host)); if (host.Length == 0) throw new ArgumentException ("The host name cannot be empty.", nameof (host)); if (port < 0 || port > 65535) throw new ArgumentOutOfRangeException (nameof (port)); CheckDisposed (); if (IsConnected) throw new InvalidOperationException ("The SmtpClient is already connected."); capabilities = SmtpCapabilities.None; AuthenticationMechanisms.Clear (); MaxSize = 0; SmtpResponse response; Stream stream; bool starttls; Uri uri; ComputeDefaultValues (host, ref port, ref options, out uri, out starttls); this.host = host; if (options == SecureSocketOptions.SslOnConnect) { var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate); try { #if COREFX ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult (); #else ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true); #endif } catch { ssl.Dispose (); throw; } secure = true; stream = ssl; } else { stream = new NetworkStream (socket, true); secure = false; } if (stream.CanTimeout) { stream.WriteTimeout = timeout; stream.ReadTimeout = timeout; } ProtocolLogger.LogConnect (uri); Stream = new SmtpStream (stream, socket, ProtocolLogger); try { // read the greeting response = Stream.ReadResponse (cancellationToken); if (response.StatusCode != SmtpStatusCode.ServiceReady) throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response); // Send EHLO and get a list of supported extensions Ehlo (cancellationToken); if (options == SecureSocketOptions.StartTls && (capabilities & SmtpCapabilities.StartTLS) == 0) throw new NotSupportedException ("The SMTP server does not support the STARTTLS extension."); if (starttls && (capabilities & SmtpCapabilities.StartTLS) != 0) { response = SendCommand ("STARTTLS", cancellationToken); if (response.StatusCode != SmtpStatusCode.ServiceReady) throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response); var tls = new SslStream (stream, false, ValidateRemoteCertificate); #if COREFX tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult (); #else tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true); #endif Stream.Stream = tls; secure = true; // Send EHLO again and get the new list of supported extensions Ehlo (cancellationToken); } connected = true; } catch { Stream.Dispose (); secure = false; Stream = null; throw; } OnConnected (); }
public async Task ConnectAsync(string host, int port, string scheme, TimeSpan timeout) { this.host = host; bool succeeded = false; try { // Connect without proxy this.TcpClient = new TcpClient(); await this.TcpClient.ConnectAsync(host, port); if (string.Equals(WebSocketConstants.Scheme, scheme, StringComparison.OrdinalIgnoreCase)) { // In the real world, web-socket will happen over HTTPS var sslStream = new SslStream(this.TcpClient.GetStream(), false, IotHubConnection.OnRemoteCertificateValidation); await sslStream.AuthenticateAsClientAsync(host); this.WebSocketStream = sslStream; } else { this.WebSocketStream = this.TcpClient.GetStream(); } var upgradeRequest = this.BuildUpgradeRequest(); byte[] upgradeRequestBytes = Encoding.ASCII.GetBytes(upgradeRequest); this.TcpClient.Client.SendTimeout = GetSocketTimeoutInMilliSeconds(timeout); // Send WebSocket Upgrade request await this.WebSocketStream.WriteAsync(upgradeRequestBytes, 0, upgradeRequestBytes.Length); // receive WebSocket Upgrade response var responseBuffer = new byte[8 * 1024]; var upgradeResponse = new HttpResponse(this.TcpClient, this.WebSocketStream, responseBuffer); await upgradeResponse.ReadAsync(timeout); if (upgradeResponse.StatusCode != HttpStatusCode.SwitchingProtocols) { // the HTTP response code was not 101 if (this.TcpClient.Connected) { this.WebSocketStream.Close(); this.TcpClient.Close(); } throw new IOException(ServerRejectedUpgradeRequest + " " + upgradeResponse); } if (!this.VerifyWebSocketUpgradeResponse(upgradeResponse.Headers)) { if (this.TcpClient.Connected) { this.WebSocketStream.Close(); this.TcpClient.Close(); } throw new IOException(UpgradeProtocolNotSupported.FormatInvariant(WebSocketConstants.SubProtocols.Amqpwsb10)); } this.State = WebSocketState.Open; succeeded = true; } finally { if (!succeeded) { this.Abort(); } } }
/// <summary> /// Initializes the stream asynchronous. /// </summary> /// <returns></returns> private Task InitializeStreamAsync() { var stream = _client.GetStream(); if (!_isSecure) { _stream = stream; return TaskAsyncHelper.Empty; } var sslStream = new SslStream(stream); _stream = sslStream; return sslStream.AuthenticateAsClientAsync(_host); }
private async Task SocketEntryAsync(CancellationToken ct) { _stream = _tcpClient.GetStream(); if (IsSecure) { var sslStream = new SslStream(_stream, true, (sender, cert, chain, sslPolicyErrors) => { if (!AcceptInsecureCertificate) { if (sslPolicyErrors == SslPolicyErrors.None) { return true; } else { OnConnectionError(new ErrorEventArgs("Server has an invalid Ssl Certificate")); } } return true; // accept all insecure certificates }); await sslStream.AuthenticateAsClientAsync(Hostname).ConfigureAwait(false); _stream = sslStream; } TaskFactory f = new TaskFactory(); await f.StartNew(async () => { await Task.Yield(); // yield to fire and forget try { await SocketLoopAsync(ct).ConfigureAwait(false); } catch (IOException ex) { OnConnectionError(new ErrorEventArgs(ex)); } catch (SocketException ex) { OnConnectionError(new ErrorEventArgs(ex)); } finally { Close(); } }, _wtoken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default).ConfigureAwait(false); }
public async Task ConnectAsync(Address address, ConnectionFactory factory) { IPAddress[] ipAddresses; IPAddress ip; if (IPAddress.TryParse(address.Host, out ip)) { ipAddresses = new IPAddress[] { ip }; } else { ipAddresses = await TaskExtensions.GetHostAddressesAsync(address.Host); } // need to handle both IPv4 and IPv6 Socket socket = null; Exception exception = null; for (int i = 0; i < ipAddresses.Length; i++) { if (ipAddresses[i] == null || (ipAddresses[i].AddressFamily == AddressFamily.InterNetwork && !Socket.OSSupportsIPv4) || (ipAddresses[i].AddressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6)) { continue; } socket = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { await socket.ConnectAsync(ipAddresses[i], address.Port); exception = null; break; } catch (Exception e) { exception = e; socket.Dispose(); socket = null; } } if (socket == null) { throw exception ?? new SocketException((int)SocketError.AddressNotAvailable); } if (factory.tcpSettings != null) { factory.tcpSettings.Configure(socket); } IAsyncTransport transport; if (address.UseSsl) { SslStream sslStream; var ssl = factory.SslInternal; if (ssl == null) { sslStream = new SslStream(new NetworkStream(socket)); await sslStream.AuthenticateAsClientAsync(address.Host); } else { sslStream = new SslStream(new NetworkStream(socket), false, ssl.RemoteCertificateValidationCallback, ssl.LocalCertificateSelectionCallback); await sslStream.AuthenticateAsClientAsync(address.Host, ssl.ClientCertificates, ssl.Protocols, ssl.CheckCertificateRevocation); } transport = new SslSocket(this, sslStream); } else { transport = new TcpSocket(this, socket); } this.socketTransport = transport; this.writer = new Writer(this, this.socketTransport); }
private async Task<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.ErrorFormat("Error occurred when validating remote certificate: [{0}], [{1}].", this.RemoteEndPoint, sslPolicyErrors); return false; }); var sslStream = new SslStream( stream, false, validateRemoteCertificate, null, _configuration.SslEncryptionPolicy); if (_configuration.SslClientCertificates == null || _configuration.SslClientCertificates.Count == 0) { await sslStream.AuthenticateAsClientAsync( // 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. } else { await sslStream.AuthenticateAsClientAsync( _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. } // 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.DebugFormat( "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; }