Ejemplo n.º 1
0
        /// <summary>
        /// Sends an email message asynchronously.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">message.</exception>
        public Task SendMailAsync(
            MailMessage message,
            string?sessionId = null,
            RemoteCertificateValidationCallback?callback = null,
            CancellationToken cancellationToken          = default)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var state = new SmtpSessionState
            {
                AuthMode        = Credentials == null ? string.Empty : SmtpDefinitions.SmtpAuthMethods.Login,
                ClientHostname  = ClientHostname,
                IsChannelSecure = EnableSsl,
                SenderAddress   = message.From.Address,
            };

            if (Credentials != null)
            {
                state.Username = Credentials.UserName;
                state.Password = Credentials.Password;
            }

            foreach (var recipient in message.To)
            {
                state.Recipients.Add(recipient.Address);
            }

            state.DataBuffer.AddRange(message.ToMimeMessage().ToArray());

            return(SendMailAsync(state, sessionId, callback, cancellationToken));
        }
Ejemplo n.º 2
0
        // constructor for outbound connections
        public MsQuicConnection(QuicClientConnectionOptions options)
        {
            _remoteEndPoint            = options.RemoteEndPoint !;
            _configuration             = SafeMsQuicConfigurationHandle.Create(options);
            _isServer                  = false;
            _remoteCertificateRequired = true;
            if (options.ClientAuthenticationOptions != null)
            {
                _revocationMode = options.ClientAuthenticationOptions.CertificateRevocationCheckMode;
                _remoteCertificateValidationCallback = options.ClientAuthenticationOptions.RemoteCertificateValidationCallback;
            }

            _stateHandle = GCHandle.Alloc(_state);
            try
            {
                // this handle is ref counted by MsQuic, so safe to dispose here.
                using SafeMsQuicConfigurationHandle config = SafeMsQuicConfigurationHandle.Create(options);

                uint status = MsQuicApi.Api.ConnectionOpenDelegate(
                    MsQuicApi.Api.Registration,
                    s_connectionDelegate,
                    GCHandle.ToIntPtr(_stateHandle),
                    out _state.Handle);

                QuicExceptionHelpers.ThrowIfFailed(status, "Could not open the connection.");
            }
            catch
            {
                _stateHandle.Free();
                throw;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Upgrades the active stream to an SSL stream if this connection object is hosted in the client.
        /// </summary>
        /// <param name="hostname">The hostname.</param>
        /// <param name="callback">The callback.</param>
        /// <returns>A tasks with <c>true</c> if the upgrade to SSL was successful; otherwise, <c>false</c>.</returns>
        public async Task <bool> UpgradeToSecureAsClientAsync(
            string?hostname = null,
            RemoteCertificateValidationCallback?callback = null)
        {
            if (IsActiveStreamSecure)
            {
                return(true);
            }

            var secureStream = callback == null
                ? new SslStream(NetworkStream, true)
                : new SslStream(NetworkStream, true, callback);

            try
            {
                await secureStream.AuthenticateAsClientAsync(hostname ?? Network.HostName.ToLowerInvariant()).ConfigureAwait(false);

                SecureStream = secureStream;
            }
            catch (Exception ex)
            {
                secureStream.Dispose();
                ConnectionFailure(this, new ConnectionFailureEventArgs(ex));
                return(false);
            }

            return(true);
        }
Ejemplo n.º 4
0
        // constructor for outbound connections
        public MsQuicConnection(QuicClientConnectionOptions options)
        {
            _remoteEndPoint            = options.RemoteEndPoint !;
            _configuration             = SafeMsQuicConfigurationHandle.Create(options);
            _isServer                  = false;
            _remoteCertificateRequired = true;
            if (options.ClientAuthenticationOptions != null)
            {
                _revocationMode = options.ClientAuthenticationOptions.CertificateRevocationCheckMode;
                _remoteCertificateValidationCallback = options.ClientAuthenticationOptions.RemoteCertificateValidationCallback;
            }

            _state.StateGCHandle = GCHandle.Alloc(_state);
            try
            {
                uint status = MsQuicApi.Api.ConnectionOpenDelegate(
                    MsQuicApi.Api.Registration,
                    s_connectionDelegate,
                    GCHandle.ToIntPtr(_state.StateGCHandle),
                    out _state.Handle);

                QuicExceptionHelpers.ThrowIfFailed(status, "Could not open the connection.");
            }
            catch
            {
                _state.StateGCHandle.Free();
                throw;
            }

            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(_state, $"{TraceId()} Outbound connection created");
            }
        }
Ejemplo n.º 5
0
#pragma warning restore IDE0052 // Remove unread private members

        /// <summary>
        /// Initializes a new instance of the <see cref="MllpServer"/> class.
        /// </summary>
        /// <param name="endPoint">The <see cref="IPEndPoint"/> the server will listen on.</param>
        /// <param name="messageLog">The <see cref="IMessageLog"/> to use for logging incoming messages.</param>
        /// <param name="middleware">The message handling middleware.</param>
        /// <param name="cleanupInterval">The interval between cleaning up client connections.</param>
        /// <param name="parser">The <see cref="PipeParser"/> to use for parsing and encoding.</param>
        /// <param name="encoding">The <see cref="Encoding"/> to use for network transfers.</param>
        /// <param name="serverCertificate">The certificates to use for secure connections.</param>
        /// <param name="userCertificateValidationCallback">Optional certificate validation callback.</param>
        public MllpServer(
            IPEndPoint endPoint,
            IMessageLog messageLog,
            IHl7MessageMiddleware middleware,
            TimeSpan cleanupInterval          = default,
            PipeParser?parser                 = null,
            Encoding?encoding                 = null,
            X509Certificate?serverCertificate = null,
            RemoteCertificateValidationCallback?userCertificateValidationCallback = null)
        {
            _messageLog        = messageLog;
            _middleware        = middleware;
            _parser            = parser;
            _encoding          = encoding ?? Encoding.ASCII;
            _serverCertificate = serverCertificate;
            _userCertificateValidationCallback = userCertificateValidationCallback;
            _listener       = new TcpListener(endPoint);
            cleanupInterval = cleanupInterval == default
                ? TimeSpan.FromSeconds(5)
                : cleanupInterval;
            _timer = new Timer(
                CleanConnections,
                null,
                cleanupInterval,
                cleanupInterval);
        }
Ejemplo n.º 6
0
 internal SslAuthenticationOptions(ServerOptionsSelectionCallback optionCallback, object?state, RemoteCertificateValidationCallback?remoteCallback)
 {
     CheckCertName          = false;
     TargetHost             = string.Empty;
     IsServer               = true;
     UserState              = state;
     ServerOptionDelegate   = optionCallback;
     CertValidationDelegate = remoteCallback;
 }
Ejemplo n.º 7
0
 public SslConnectionOptions(QuicConnection connection, bool isClient, string?targetHost, bool certificateRequired, X509RevocationMode revocationMode, RemoteCertificateValidationCallback?validationCallback)
 {
     _connection          = connection;
     _isClient            = isClient;
     _targetHost          = targetHost;
     _certificateRequired = certificateRequired;
     _revocationMode      = revocationMode;
     _validationCallback  = validationCallback;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Sends an email message using a session state object.
        /// Credentials, Enable SSL and Client Hostname are NOT taken from the state object but
        /// rather from the properties of this class.
        /// </summary>
        /// <param name="sessionState">The state.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">sessionState.</exception>
        public Task SendMailAsync(
            SmtpSessionState sessionState,
            string?sessionId = null,
            RemoteCertificateValidationCallback?callback = null,
            CancellationToken cancellationToken          = default)
        {
            if (sessionState == null)
            {
                throw new ArgumentNullException(nameof(sessionState));
            }

            return(SendMailAsync(new[] { sessionState }, sessionId, callback, cancellationToken));
        }
Ejemplo n.º 9
0
            public State(QuicListenerOptions options)
            {
                ConnectionConfiguration = SafeMsQuicConfigurationHandle.Create(options);
                if (options.ServerAuthenticationOptions != null)
                {
                    RemoteCertificateRequired           = options.ServerAuthenticationOptions.ClientCertificateRequired;
                    RevocationMode                      = options.ServerAuthenticationOptions.CertificateRevocationCheckMode;
                    RemoteCertificateValidationCallback = options.ServerAuthenticationOptions.RemoteCertificateValidationCallback;
                }

                AcceptConnectionQueue = Channel.CreateBounded <MsQuicConnection>(new BoundedChannelOptions(options.ListenBacklog)
                {
                    SingleReader = true,
                    SingleWriter = true
                });
            }
Ejemplo n.º 10
0
        public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                         LocalCertificateSelectionCallback?userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
            : base(innerStream, leaveInnerStreamOpen)
        {
            if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption)
            {
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(encryptionPolicy));
            }

            _userCertificateValidationCallback = userCertificateValidationCallback;
            _userCertificateSelectionCallback  = userCertificateSelectionCallback;
            _encryptionPolicy       = encryptionPolicy;
            _certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
            _certSelectionDelegate  = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);

            _innerStream = innerStream;
        }
Ejemplo n.º 11
0
        public static ValueTask <SslStream> EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Stream stream, CancellationToken cancellationToken)
        {
            // If there's a cert validation callback, and if it came from HttpClientHandler,
            // wrap the original delegate in order to change the sender to be the request message (expected by HttpClientHandler's delegate).
            RemoteCertificateValidationCallback?callback = sslOptions.RemoteCertificateValidationCallback;

            if (callback != null && callback.Target is CertificateCallbackMapper mapper)
            {
                sslOptions = sslOptions.ShallowClone(); // Clone as we're about to mutate it and don't want to affect the cached copy
                Func <HttpRequestMessage, X509Certificate2?, X509Chain?, SslPolicyErrors, bool> localFromHttpClientHandler = mapper.FromHttpClientHandler;
                HttpRequestMessage localRequest = request;
                sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) =>
                                                                 localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors);
            }

            // Create the SslStream, authenticate, and return it.
            return(EstablishSslConnectionAsyncCore(stream, sslOptions, cancellationToken));
        }
Ejemplo n.º 12
0
#pragma warning restore IDE0052 // Remove unread private members

        private MllpClient(
            string address,
            int port,
            IMessageLog messageLog,
            PipeParser parser,
            Encoding encoding,
            X509CertificateCollection?clientCertificates,
            RemoteCertificateValidationCallback?
            userCertificateValidationCallback)
        {
            _address            = address;
            _port               = port;
            _messageLog         = messageLog;
            _parser             = parser;
            _encoding           = encoding;
            _clientCertificates = clientCertificates;
            _userCertificateValidationCallback =
                userCertificateValidationCallback;
        }
Ejemplo n.º 13
0
    public EasyHttpClientOptions(
        int retCount          = Consts.Numbers.EasyHttpClient_DefaultTryCount, int retryIntervalMsecs = Consts.Numbers.EasyHttpClient_DefaultRetryIntervalMsecs,
        bool randomInterval   = true,
        string basicUsername  = "", string basicPassword = "",
        WebApiOptions?options = null, RemoteCertificateValidationCallback?sslCallback = null)
    {
        options ??= new WebApiOptions();

        this.TryCount = Math.Max(retCount, 1);

        this.RetryIntervalMsecs = Math.Max(retryIntervalMsecs, 1);

        this.RandomInterval = randomInterval;

        this.WebApiOptions = options;
        this.SslCallback   = sslCallback;

        this.BasicUsername = basicUsername._NonNull();
        this.BasicPassword = basicPassword._NonNull();
    }
Ejemplo n.º 14
0
        public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                         LocalCertificateSelectionCallback?userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
            : base(innerStream, leaveInnerStreamOpen)
        {
#pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete
            if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption)
            {
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(encryptionPolicy));
            }
#pragma warning restore SYSLIB0040

            _sslAuthenticationOptions.EncryptionPolicy       = encryptionPolicy;
            _sslAuthenticationOptions.CertValidationDelegate = userCertificateValidationCallback;
            _sslAuthenticationOptions.CertSelectionDelegate  = userCertificateSelectionCallback;

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Log.SslStreamCtor(this, innerStream);
            }
        }
Ejemplo n.º 15
0
        public static async Task <MllpHost> Create(
            TcpClient tcpClient,
            IMessageLog messageLog,
            IHl7MessageMiddleware middleware,
            PipeParser?parser = null,
            Encoding?encoding = null,
            X509Certificate?serverCertificate = null,
            RemoteCertificateValidationCallback?
            userCertificateValidationCallback = null)
        {
            var host = new MllpHost(
                tcpClient,
                messageLog,
                parser ?? new PipeParser(),
                encoding ?? Encoding.ASCII,
                middleware);
            Stream stream = tcpClient.GetStream();

            if (serverCertificate != null)
            {
                var ssl = new SslStream(
                    stream,
                    false,
                    userCertificateValidationCallback);
                await ssl.AuthenticateAsServerAsync(
                    serverCertificate,
                    true,
                    SslProtocols.Tls11 | SslProtocols.Tls12,
                    false)
                .ConfigureAwait(false);

                host._stream = ssl;
            }
            else
            {
                host._stream = stream;
            }

            host._readThread = host.ReadStream(host._tokenSource.Token);
            return(host);
        }
Ejemplo n.º 16
0
        internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback?remoteCallback, LocalCertSelectionCallback?localCallback)
        {
            Debug.Assert(sslClientAuthenticationOptions.TargetHost != null);

            // Common options.
            AllowRenegotiation     = sslClientAuthenticationOptions.AllowRenegotiation;
            ApplicationProtocols   = sslClientAuthenticationOptions.ApplicationProtocols;
            CertValidationDelegate = remoteCallback;
            CheckCertName          = true;
            EnabledSslProtocols    = FilterOutIncompatibleSslProtocols(sslClientAuthenticationOptions.EnabledSslProtocols);
            EncryptionPolicy       = sslClientAuthenticationOptions.EncryptionPolicy;
            IsServer           = false;
            RemoteCertRequired = true;
            TargetHost         = sslClientAuthenticationOptions.TargetHost !;

            // Client specific options.
            CertSelectionDelegate          = localCallback;
            CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
            ClientCertificates             = sslClientAuthenticationOptions.ClientCertificates;
            CipherSuitesPolicy             = sslClientAuthenticationOptions.CipherSuitesPolicy;
        }
Ejemplo n.º 17
0
        // constructor for inbound connections
        public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback?remoteCertificateValidationCallback = null)
        {
            _state.Handle                        = handle;
            _state.StateGCHandle                 = GCHandle.Alloc(_state);
            _state.Connected                     = true;
            _isServer                            = true;
            _localEndPoint                       = localEndPoint;
            _remoteEndPoint                      = remoteEndPoint;
            _remoteCertificateRequired           = remoteCertificateRequired;
            _revocationMode                      = revocationMode;
            _remoteCertificateValidationCallback = remoteCertificateValidationCallback;

            if (_remoteCertificateRequired)
            {
                // We need to link connection for the validation callback.
                // We need to be able to find the connection in HandleEventPeerCertificateReceived
                // and dispatch it as sender to validation callback.
                // After that Connection will be set back to null.
                _state.Connection = this;
            }

            try
            {
                MsQuicApi.Api.SetCallbackHandlerDelegate(
                    _state.Handle,
                    s_connectionDelegate,
                    GCHandle.ToIntPtr(_state.StateGCHandle));
            }
            catch
            {
                _state.StateGCHandle.Free();
                throw;
            }

            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(_state, $"{TraceId()} Inbound connection created");
            }
        }
Ejemplo n.º 18
0
        private static SslClientAuthenticationOptions SetUpRemoteCertificateValidationCallback(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request)
        {
            // If there's a cert validation callback, and if it came from HttpClientHandler,
            // wrap the original delegate in order to change the sender to be the request message (expected by HttpClientHandler's delegate).
            RemoteCertificateValidationCallback?callback = sslOptions.RemoteCertificateValidationCallback;

            if (callback != null && callback.Target is CertificateCallbackMapper mapper)
            {
                sslOptions = sslOptions.ShallowClone(); // Clone as we're about to mutate it and don't want to affect the cached copy
                Func <HttpRequestMessage, X509Certificate2?, X509Chain?, SslPolicyErrors, bool> localFromHttpClientHandler = mapper.FromHttpClientHandler;
                HttpRequestMessage localRequest = request;
                sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) =>
                {
                    Debug.Assert(localRequest != null);
                    bool result = localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors);
                    localRequest = null !; // ensure the SslOptions and this callback don't keep the first HttpRequestMessage alive indefinitely
                    return(result);
                };
            }

            return(sslOptions);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Creates a new instance of the <see cref="MllpClient"/> class.
        /// </summary>
        /// <param name="address"></param>
        /// <param name="port"></param>
        /// <param name="messageLog"></param>
        /// <param name="parser"></param>
        /// <param name="encoding"></param>
        /// <param name="clientCertificates"></param>
        /// <param name="userCertificateValidationCallback"></param>
        /// <returns></returns>
        public static async Task <IHostConnection> Create(
            string address,
            int port,
            IMessageLog?messageLog = null,
            PipeParser?parser      = null,
            Encoding?encoding      = null,
            X509CertificateCollection?clientCertificates = null,
            RemoteCertificateValidationCallback?
            userCertificateValidationCallback = null)
        {
            var instance = new MllpClient(
                address,
                port,
                messageLog ?? NullLog.Get(),
                parser ?? new PipeParser(),
                encoding ?? Encoding.ASCII,
                clientCertificates,
                userCertificateValidationCallback);
            await instance.Setup().ConfigureAwait(false);

            return(instance);
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Creates a Glacier2 session.
 /// </summary>
 /// <param name="callback">The callback for notifications about session
 /// establishment.</param>
 /// <param name="properties">Optional properties used for communicator initialization.</param>
 /// <param name="logger">Optional logger used for communicator initialization.</param>
 /// <param name="observer">Optional communicator observer used for communicator initialization.</param>
 /// <param name="certificates">The user certificates to use with the SSL transport.</param>
 /// <param name="caCertificates">The certificate authorities to use with the SSL transport.</param>
 /// <param name="certificateValidationCallback">The certificate validation callback to use with the SSL transport.</param>
 /// <param name="passwordCallback">The password callback delegate to use with the SSL transport.</param>
 /// <param name="finderStr">The stringified Ice.RouterFinder proxy.</param>
 /// <param name="useCallbacks">True if the session should create an object adapter for receiving callbacks.</param>
 internal SessionHelper(ISessionCallback callback,
                        string finderStr,
                        bool useCallbacks,
                        Dictionary <string, string> properties,
                        ILogger?logger = null,
                        ICommunicatorObserver?observer            = null,
                        X509Certificate2Collection?certificates   = null,
                        X509Certificate2Collection?caCertificates = null,
                        RemoteCertificateValidationCallback?certificateValidationCallback = null,
                        IPasswordCallback?passwordCallback = null)
 {
     _callback       = callback;
     _finderStr      = finderStr;
     _useCallbacks   = useCallbacks;
     _properties     = properties;
     _logger         = logger;
     _observer       = observer;
     _certificates   = certificates;
     _caCertificates = caCertificates;
     _certificateValidationCallback = certificateValidationCallback;
     _passwordCallback = passwordCallback;
 }
Ejemplo n.º 21
0
        /// <summary>Creates a SessionFactory object.</summary>
        /// <param name="callback">The callback for notifications about session establishment.</param>
        /// <param name="properties">Optional properties used for communicator initialization.</param>
        /// <param name="logger">Optional logger used for communicator initialization.</param>
        /// <param name="observer">Optional communicator observer used for communicator initialization.</param>
        /// <param name="certificates">Optional certificates used by secure transports.</param>
        /// <param name="caCertificates">Optional CA certificates used by secure transports.</param>
        /// /// <param name="certificateSelectionCallback">Optional certificate selection callback used by secure
        /// transports.</param>
        /// <param name="certificateValidationCallback">Optional certificate validation callback used by secure
        /// transports.</param>
        /// <param name="passwordCallback">Optional password callback used by secure transports.</param>
        public SessionFactoryHelper(
            ISessionCallback callback,
            Dictionary <string, string> properties,
            ILogger?logger = null,
            ICommunicatorObserver?observer            = null,
            X509Certificate2Collection?certificates   = null,
            X509Certificate2Collection?caCertificates = null,
            LocalCertificateSelectionCallback?certificateSelectionCallback    = null,
            RemoteCertificateValidationCallback?certificateValidationCallback = null,
            IPasswordCallback?passwordCallback = null)
        {
            _callback       = callback;
            _properties     = properties;
            _logger         = logger;
            _observer       = observer;
            _certificates   = certificates;
            _caCertificates = caCertificates;
            _certificateSelectionCallback  = certificateSelectionCallback;
            _certificateValidationCallback = certificateValidationCallback;
            _passwordCallback = passwordCallback;

            _properties["Ice.RetryIntervals"] = "-1";
        }
Ejemplo n.º 22
0
 public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                  LocalCertificateSelectionCallback?userCertificateSelectionCallback)
     : this(innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, userCertificateSelectionCallback, EncryptionPolicy.RequireEncryption)
 {
 }
Ejemplo n.º 23
0
        // constructor for inbound connections
        public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback?remoteCertificateValidationCallback = null, ServerCertificateSelectionCallback?serverCertificateSelectionCallback = null)
        {
            _state.Handle                              = handle;
            _state.StateGCHandle                       = GCHandle.Alloc(_state);
            _state.Connected                           = true;
            _state.RemoteCertificateRequired           = remoteCertificateRequired;
            _state.RevocationMode                      = revocationMode;
            _state.RemoteCertificateValidationCallback = remoteCertificateValidationCallback;
            _state.IsServer                            = true;
            _localEndPoint                             = localEndPoint;
            _remoteEndPoint                            = remoteEndPoint;

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state));
                MsQuicApi.Api.SetCallbackHandlerDelegate(
                    _state.Handle,
                    s_connectionDelegate,
                    GCHandle.ToIntPtr(_state.StateGCHandle));
            }
            catch
            {
                _state.StateGCHandle.Free();
                throw;
            }

            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(_state, $"{TraceId()} Inbound connection created");
            }
        }
Ejemplo n.º 24
0
        internal SslEngine(
            Communicator communicator,
            X509Certificate2Collection?certificates,
            X509Certificate2Collection?caCertificates,
            LocalCertificateSelectionCallback?certificateSelectionCallback,
            RemoteCertificateValidationCallback?certificateValidationCallback,
            IPasswordCallback?passwordCallback)
        {
            _logger            = communicator.Logger;
            SecurityTraceLevel = communicator.GetPropertyAsInt("IceSSL.Trace.Security") ?? 0;
            _trustManager      = new SslTrustManager(communicator);

            CertificateSelectionCallback        = certificateSelectionCallback;
            RemoteCertificateValidationCallback = certificateValidationCallback;
            PasswordCallback = passwordCallback;

            Certs   = certificates;
            CaCerts = caCertificates;

            // Check for a default directory. We look in this directory for files mentioned in the configuration.
            _defaultDir = communicator.GetProperty("IceSSL.DefaultDir") ?? "";

            string?certStoreLocation = communicator.GetProperty("IceSSL.CertStoreLocation");

            if (certStoreLocation != null && CertificateSelectionCallback != null)
            {
                throw new InvalidConfigurationException(
                          "the property `IceSSL.CertStoreLocation' is incompatible with the certificate selection callback");
            }
            certStoreLocation ??= "CurrentUser";
            StoreLocation storeLocation;

            if (certStoreLocation == "CurrentUser")
            {
                storeLocation = StoreLocation.CurrentUser;
            }
            else if (certStoreLocation == "LocalMachine")
            {
                storeLocation = StoreLocation.LocalMachine;
            }
            else
            {
                _logger.Warning($"Invalid IceSSL.CertStoreLocation value `{certStoreLocation}' adjusted to `CurrentUser'");
                storeLocation = StoreLocation.CurrentUser;
            }
            UseMachineContext = certStoreLocation == "LocalMachine";

            // Protocols selects which protocols to enable
            SslProtocols = ParseProtocols(communicator.GetPropertyAsList("IceSSL.Protocols"));

            // VerifyDepthMax establishes the maximum length of a peer's certificate chain, including the peer's
            // certificate. A value of 0 means there is no maximum.
            int?verifyDepthMax = communicator.GetPropertyAsInt("IceSSL.VerifyDepthMax");

            if (verifyDepthMax != null && RemoteCertificateValidationCallback != null)
            {
                throw new InvalidConfigurationException(
                          "the property `IceSSL.VerifyDepthMax' check is incompatible with the custom remote certificate validation callback");
            }
            _verifyDepthMax = verifyDepthMax ?? 3;

            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            CheckCRL = communicator.GetPropertyAsInt("IceSSL.CheckCRL") ?? 0;

            // If the user hasn't supplied a certificate collection, we need to examine the property settings.
            if (Certs == null)
            {
                // If IceSSL.CertFile is defined, load a certificate from a file and add it to the collection.
                // TODO: tracing?
                string?certFile = communicator.GetProperty("IceSSL.CertFile");
                if (certFile != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.CertFile' is incompatible with the certificate selection callback");
                }

                string?passwordStr = communicator.GetProperty("IceSSL.Password");
                if (passwordStr != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.Password' is incompatible with the certificate selection callback");
                }

                string?findCert = communicator.GetProperty("IceSSL.FindCert");
                if (findCert != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.FindCert' is incompatible with the certificate selection callback");
                }
                Certs = new X509Certificate2Collection();
                const string findPrefix = "IceSSL.FindCert.";
                Dictionary <string, string> findCertProps = communicator.GetProperties(forPrefix: findPrefix);

                if (certFile != null)
                {
                    if (!CheckPath(ref certFile))
                    {
                        throw new FileNotFoundException($"certificate file not found: `{certFile}'", certFile);
                    }

                    SecureString?password = null;
                    if (passwordStr != null)
                    {
                        password = CreateSecureString(passwordStr);
                    }
                    else if (PasswordCallback != null)
                    {
                        password = PasswordCallback(certFile);
                    }

                    try
                    {
                        X509Certificate2    cert;
                        X509KeyStorageFlags importFlags;
                        if (UseMachineContext)
                        {
                            importFlags = X509KeyStorageFlags.MachineKeySet;
                        }
                        else
                        {
                            importFlags = X509KeyStorageFlags.UserKeySet;
                        }

                        if (password != null)
                        {
                            cert = new X509Certificate2(certFile, password, importFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", importFlags);
                        }
                        Certs.Add(cert);
                    }
                    catch (CryptographicException ex)
                    {
                        throw new InvalidConfigurationException(
                                  $"error while attempting to load certificate from `{certFile}'", ex);
                    }
                }
                else if (findCert != null)
                {
                    string certStore = communicator.GetProperty("IceSSL.CertStore") ?? "My";
                    Certs.AddRange(FindCertificates("IceSSL.FindCert", storeLocation, certStore, findCert));
                    if (Certs.Count == 0)
                    {
                        throw new InvalidConfigurationException("no certificates found");
                    }
                }
            }

            if (CaCerts == null)
            {
                string?certAuthFile = communicator.GetProperty("IceSSL.CAs");
                if (certAuthFile != null && RemoteCertificateValidationCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.CAs' is incompatible with the custom remote certificate validation callback");
                }

                bool?usePlatformCAs = communicator.GetPropertyAsBool("IceSSL.UsePlatformCAs");
                if (usePlatformCAs != null && RemoteCertificateValidationCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.UsePlatformCAs' is incompatible with the custom remote certificate validation callback");
                }

                if (RemoteCertificateValidationCallback == null)
                {
                    if (certAuthFile != null || !(usePlatformCAs ?? false))
                    {
                        CaCerts = new X509Certificate2Collection();
                    }

                    if (certAuthFile != null)
                    {
                        if (!CheckPath(ref certAuthFile))
                        {
                            throw new FileNotFoundException("CA certificate file not found: `{certAuthFile}'",
                                                            certAuthFile);
                        }

                        try
                        {
                            using FileStream fs = File.OpenRead(certAuthFile);
                            byte[] data = new byte[fs.Length];
                            fs.Read(data, 0, data.Length);

                            string strbuf = "";
                            try
                            {
                                strbuf = System.Text.Encoding.UTF8.GetString(data);
                            }
                            catch (Exception)
                            {
                                // Ignore
                            }

                            if (strbuf.Length == data.Length)
                            {
                                int  size, startpos, endpos = 0;
                                bool first = true;
                                while (true)
                                {
                                    startpos = strbuf.IndexOf("-----BEGIN CERTIFICATE-----", endpos);
                                    if (startpos != -1)
                                    {
                                        endpos = strbuf.IndexOf("-----END CERTIFICATE-----", startpos);
                                        size   = endpos - startpos + "-----END CERTIFICATE-----".Length;
                                    }
                                    else if (first)
                                    {
                                        startpos = 0;
                                        endpos   = strbuf.Length;
                                        size     = strbuf.Length;
                                    }
                                    else
                                    {
                                        break;
                                    }

                                    byte[] cert = new byte[size];
                                    Buffer.BlockCopy(data, startpos, cert, 0, size);
                                    CaCerts !.Import(cert);
                                    first = false;
                                }
                            }
                            else
                            {
                                CaCerts !.Import(data);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new InvalidConfigurationException(
                                      $"error while attempting to load CA certificate from {certAuthFile}", ex);
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        // constructor for inbound connections
        public unsafe MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, MsQuicListener.State listenerState, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback?remoteCertificateValidationCallback = null, ServerCertificateSelectionCallback?serverCertificateSelectionCallback = null)
        {
            _state.Handle                              = handle;
            _state.StateGCHandle                       = GCHandle.Alloc(_state);
            _state.RemoteCertificateRequired           = remoteCertificateRequired;
            _state.RevocationMode                      = revocationMode;
            _state.RemoteCertificateValidationCallback = remoteCertificateValidationCallback;
            _state.IsServer                            = true;
            _localEndPoint                             = localEndPoint;
            _remoteEndPoint                            = remoteEndPoint;

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
                MsQuicApi.Api.ApiTable->SetConnectionCallback(_state.Handle.QuicHandle, &NativeCallback, (void *)GCHandle.ToIntPtr(_state.StateGCHandle));
            }
            catch
            {
                _state.StateGCHandle.Free();
                throw;
            }

            _state.ListenerState = listenerState;
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(_state, $"{handle} Inbound connection created");
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Sends an array of email messages using a session state object.
        /// Credentials, Enable SSL and Client Hostname are NOT taken from the state object but
        /// rather from the properties of this class.
        /// </summary>
        /// <param name="sessionStates">The session states.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">sessionStates.</exception>
        /// <exception cref="SecurityException">Could not upgrade the channel to SSL.</exception>
        /// <exception cref="SmtpException">Defines an SMTP Exceptions class.</exception>
        public async Task SendMailAsync(
            IEnumerable <SmtpSessionState> sessionStates,
            string?sessionId = null,
            RemoteCertificateValidationCallback?callback = null,
            CancellationToken cancellationToken          = default)
        {
            if (sessionStates == null)
            {
                throw new ArgumentNullException(nameof(sessionStates));
            }

            using var tcpClient = new TcpClient();
            await tcpClient.ConnectAsync(Host, Port, cancellationToken).ConfigureAwait(false);

            using var connection = new Connection(tcpClient, Encoding.UTF8, "\r\n", true, 1000);
            var sender = new SmtpSender(sessionId);

            try
            {
                // Read the greeting message
                sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                // EHLO 1
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

                // STARTTLS
                if (EnableSsl)
                {
                    sender.RequestText = $"{SmtpCommandNames.STARTTLS}";

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();

                    if (await connection.UpgradeToSecureAsClientAsync(callback: callback).ConfigureAwait(false) == false)
                    {
                        throw new SecurityException("Could not upgrade the channel to SSL.");
                    }
                }

                // EHLO 2
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

                // AUTH
                if (Credentials != null)
                {
                    var auth = new ConnectionAuth(connection, sender, Credentials);
                    await auth.AuthenticateAsync(cancellationToken).ConfigureAwait(false);
                }

                foreach (var sessionState in sessionStates)
                {
                    {
                        // MAIL FROM
                        sender.RequestText = $"{SmtpCommandNames.MAIL} FROM:<{sessionState.SenderAddress}>";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    // RCPT TO
                    foreach (var recipient in sessionState.Recipients)
                    {
                        sender.RequestText = $"{SmtpCommandNames.RCPT} TO:<{recipient}>";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    {
                        // DATA
                        sender.RequestText = $"{SmtpCommandNames.DATA}";

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

                    {
                        // CONTENT
                        var dataTerminator = sessionState.DataBuffer
                                             .Skip(sessionState.DataBuffer.Count - 5)
                                             .ToText();

                        sender.RequestText = $"Buffer ({sessionState.DataBuffer.Count} bytes)";

                        await connection.WriteDataAsync(sessionState.DataBuffer.ToArray(), true, cancellationToken).ConfigureAwait(false);

                        if (!dataTerminator.EndsWith(SmtpDefinitions.SmtpDataCommandTerminator, StringComparison.OrdinalIgnoreCase))
                        {
                            await connection.WriteTextAsync(SmtpDefinitions.SmtpDataCommandTerminator, cancellationToken).ConfigureAwait(false);
                        }

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }
                }

                {
                    // QUIT
                    sender.RequestText = $"{SmtpCommandNames.QUIT}";

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();
                }
            }
            catch (Exception ex)
            {
                throw new SmtpException($"Could not send email - Session ID {sessionId}. {ex.Message}\r\n    Last Request: {sender.RequestText}\r\n    Last Reply: {sender.ReplyText}");
            }
        }
Ejemplo n.º 27
0
    public async Task SendAsync(SmtpConfig smtp, CancellationToken cancel = default)
    {
        using SmtpClient c = new SmtpClient(smtp.SmtpServer, smtp.SmtpPort);
        c.DeliveryMethod   = SmtpDeliveryMethod.Network;
        c.EnableSsl        = smtp.UseSSL;

        if (smtp.Username._IsFilled() && smtp.Password._IsFilled())
        {
            c.UseDefaultCredentials = false;
            c.Credentials           = new System.Net.NetworkCredential(smtp.Username, smtp.Password);
        }

        MailMessage mail = new MailMessage(CharsetList.NormalizeMailAddress(this.From),
                                           CharsetList.NormalizeMailAddress(this.To));

        Encoding         bodyEnc  = CharsetList.GetAppropriateCharset(this.Body);
        TransferEncoding bodyTran = SmtpCharsetList.GetTransferEncoding(bodyEnc);

        byte[]       bodyData = bodyEnc.GetBytes(this.Body);
        MemoryStream ms       = new MemoryStream(bodyData);

        AlternateView alt = new AlternateView(ms,
                                              new ContentType("text/plain; charset=" + bodyEnc.WebName));

        alt.TransferEncoding = bodyTran;

        if (Str.IsEmptyStr(this.Body) == false)
        {
            mail.AlternateViews.Add(alt);
        }
        mail.Body         = "";
        mail.BodyEncoding = bodyEnc;

        // HTML メールの場合
        if (Str.IsEmptyStr(this.BodyHtml) == false)
        {
            Encoding         htmlEnc  = CharsetList.GetAppropriateCharset(this.BodyHtml);
            TransferEncoding htmlTran = SmtpCharsetList.GetTransferEncoding(htmlEnc);

            byte[] htmlData = htmlEnc.GetBytes(this.BodyHtml);
            ms = new MemoryStream(htmlData);

            AlternateView alt2 = new AlternateView(ms,
                                                   new ContentType("text/html; charset=" + htmlEnc.WebName));

            // リソースファイル
            foreach (LinkedResource a in LinkedResourceList)
            {
                alt2.LinkedResources.Add(a);
            }

            mail.AlternateViews.Add(alt2);
        }

        // 添付ファイル
        foreach (Attachment a in AttatchedFileList)
        {
            mail.Attachments.Add(a);
        }

        Encoding subjectEnc = CharsetList.GetAppropriateCharset(this.Subject);

        byte[] subjectData = subjectEnc.GetBytes(this.Subject);
        string subjectText = string.Format("=?{0}?B?{1}?=", subjectEnc.WebName.ToUpperInvariant(),
                                           Convert.ToBase64String(subjectData, Base64FormattingOptions.None));

        if (Str.IsAscii(this.Subject))
        {
            subjectText = this.Subject;
        }

        mail.Subject = subjectText;

        if (this.ReplyTo != null)
        {
            //                mail.ReplyTo = this.ReplyTo;
            mail.ReplyToList.Add(this.ReplyTo);
        }

        foreach (MailAddress cc in CcList)
        {
            mail.CC.Add(cc);
        }

        foreach (MailAddress bcc in BccList)
        {
            mail.Bcc.Add(bcc);
        }

        mail.Headers.Add("X-Mailer", XMailer);
        mail.Headers.Add("X-MSMail-Priority", MSMailPriority);
        mail.Headers.Add("X-Priority", MailPriority);
        mail.Headers.Add("X-MimeOLE", MimeOLE);

        // SSL 証明書をチェック いたしません!!
        RemoteCertificateValidationCallback?sslCallbackBackup = ServicePointManager.ServerCertificateValidationCallback;

        if (c.EnableSsl)
        {
            ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
        }

        try
        {
            await c.SendMailAsync(mail);
        }
        finally
        {
            if (c.EnableSsl)
            {
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = sslCallbackBackup;
                }
                catch { }
            }
        }
    }
Ejemplo n.º 28
0
 public static async Task <SimpleHttpDownloaderResult> DownloadAsync(string url, WebMethods method = WebMethods.GET, bool printStatus = false, WebApiOptions?options = null, RemoteCertificateValidationCallback?sslServerCertValicationCallback = null, CancellationToken cancel = default, string?postContentType = Consts.MimeTypes.FormUrlEncoded, params (string name, string?value)[] queryList)
Ejemplo n.º 29
0
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback?remoteCallback, LocalCertSelectionCallback?localCallback)
        {
            ThrowIfExceptional();

            if (_context != null && _context.IsValidContext)
            {
                throw new InvalidOperationException(SR.net_auth_reauth);
            }

            if (_context != null && IsServer)
            {
                throw new InvalidOperationException(SR.net_auth_client_server);
            }

            ArgumentNullException.ThrowIfNull(sslClientAuthenticationOptions.TargetHost, nameof(sslClientAuthenticationOptions.TargetHost));

            _exception = null;
            try
            {
                _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback);
                _context = new SecureChannel(_sslAuthenticationOptions, this);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
Ejemplo n.º 30
0
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback?remoteCallback, LocalCertSelectionCallback?localCallback)
        {
            // Without setting (or using) these members you will get a build exception in the unit test project.
            // The code that normally uses these in the main solution is in the implementation of SslStream.

            if (_nestedWrite == 0)
            {
            }
            _context             = null;
            _exception           = null;
            _internalBuffer      = null;
            _internalBufferCount = 0;
            _internalOffset      = 0;
            _nestedWrite         = 0;
            _handshakeCompleted  = false;
        }