Exemple #1
0
            private bool SendEHello()
            {
                IAsyncResult result = EHelloCommand.BeginSend(_connection, _connection._client.clientDomain, s_sendEHelloCallback, this);

                if (result.CompletedSynchronously)
                {
                    _connection._extensions = EHelloCommand.EndSend(result);
                    _connection.ParseExtensions(_connection._extensions);
                    // If we already have a TlsStream, this is the second EHLO cmd
                    // that we sent after TLS handshake compelted. So skip TLS and
                    // continue with Authenticate.
                    if (_connection._networkStream is TlsStream)
                    {
                        Authenticate();
                        return(true);
                    }

                    if (_connection.EnableSsl)
                    {
                        if (!_connection._serverSupportsStartTls)
                        {
                            // Either TLS is already established or server does not support TLS
                            if (!(_connection._networkStream is TlsStream))
                            {
                                throw new SmtpException(string.Format(Strings.MailServerDoesNotSupportStartTls));
                            }
                        }

                        SendStartTls();
                    }
                    else
                    {
                        Authenticate();
                    }
                    return(true);
                }
                return(false);
            }
Exemple #2
0
            private static void SendEHelloCallback(IAsyncResult result)
            {
                if (!result.CompletedSynchronously)
                {
                    ConnectAndHandshakeAsyncResult thisPtr = (ConnectAndHandshakeAsyncResult)result.AsyncState;
                    try
                    {
                        try
                        {
                            thisPtr._connection._extensions = EHelloCommand.EndSend(result);
                            thisPtr._connection.ParseExtensions(thisPtr._connection._extensions);

                            // If we already have a SSlStream, this is the second EHLO cmd
                            // that we sent after TLS handshake compelted. So skip TLS and
                            // continue with Authenticate.
                            if (thisPtr._connection._networkStream is TlsStream)
                            {
                                thisPtr.Authenticate();
                                return;
                            }
                        }

                        catch (SmtpException e)
                        {
                            if ((e.StatusCode != SmtpStatusCode.CommandUnrecognized) &&
                                (e.StatusCode != SmtpStatusCode.CommandNotImplemented))
                            {
                                throw;
                            }

                            if (!thisPtr.SendHello())
                            {
                                return;
                            }
                        }


                        if (thisPtr._connection.EnableSsl)
                        {
                            if (!thisPtr._connection._serverSupportsStartTls)
                            {
                                // Either TLS is already established or server does not support TLS
                                if (!(thisPtr._connection._networkStream is TlsStream))
                                {
                                    throw new SmtpException(Strings.MailServerDoesNotSupportStartTls);
                                }
                            }

                            thisPtr.SendStartTls();
                        }
                        else
                        {
                            thisPtr.Authenticate();
                        }
                    }
                    catch (Exception e)
                    {
                        thisPtr.InvokeCallback(e);
                    }
                }
            }
Exemple #3
0
        internal void GetConnection(string host, int port)
        {
            if (_isConnected)
            {
                throw new InvalidOperationException(Strings.SmtpAlreadyConnected);
            }

            InitializeConnection(host, port);
            _responseReader = new SmtpReplyReaderFactory(_networkStream);

            LineInfo info = _responseReader.GetNextReplyReader().ReadLine();

            switch (info.StatusCode)
            {
            case SmtpStatusCode.ServiceReady:
                break;

            default:
                throw new SmtpException(info.StatusCode, info.Line, true);
            }

            try
            {
                _extensions = EHelloCommand.Send(this, _client.clientDomain);
                ParseExtensions(_extensions);
            }
            catch (SmtpException e)
            {
                if ((e.StatusCode != SmtpStatusCode.CommandUnrecognized) &&
                    (e.StatusCode != SmtpStatusCode.CommandNotImplemented))
                {
                    throw;
                }

                HelloCommand.Send(this, _client.clientDomain);
                //if ehello isn't supported, assume basic login
                _supportedAuth = SupportedAuth.Login;
            }

            if (_enableSsl)
            {
                if (!_serverSupportsStartTls)
                {
                    // Either TLS is already established or server does not support TLS
                    if (!(_networkStream is TlsStream))
                    {
                        throw new SmtpException(Strings.MailServerDoesNotSupportStartTls);
                    }
                }

                StartTlsCommand.Send(this);
                TlsStream tlsStream = new TlsStream(_networkStream, _tcpClient.Client, host, _clientCertificates);
                tlsStream.AuthenticateAsClient();
                _networkStream  = tlsStream;
                _responseReader = new SmtpReplyReaderFactory(_networkStream);

                // According to RFC 3207: The client SHOULD send an EHLO command
                // as the first command after a successful TLS negotiation.
                _extensions = EHelloCommand.Send(this, _client.clientDomain);
                ParseExtensions(_extensions);
            }

            // if no credentials were supplied, try anonymous
            // servers don't appear to anounce that they support anonymous login.
            if (_credentials != null)
            {
                for (int i = 0; i < _authenticationModules.Length; i++)
                {
                    //only authenticate if the auth protocol is supported  - chadmu
                    if (!AuthSupported(_authenticationModules[i]))
                    {
                        continue;
                    }

                    NetworkCredential credential = _credentials.GetCredential(host, port, _authenticationModules[i].AuthenticationType);
                    if (credential == null)
                    {
                        continue;
                    }

                    Authorization auth = SetContextAndTryAuthenticate(_authenticationModules[i], credential, null);

                    if (auth != null && auth.Message != null)
                    {
                        info = AuthCommand.Send(this, _authenticationModules[i].AuthenticationType, auth.Message);

                        if (info.StatusCode == SmtpStatusCode.CommandParameterNotImplemented)
                        {
                            continue;
                        }

                        while ((int)info.StatusCode == 334)
                        {
                            auth = _authenticationModules[i].Authenticate(info.Line, null, this, _client.TargetName, _channelBindingToken);
                            if (auth == null)
                            {
                                throw new SmtpException(Strings.SmtpAuthenticationFailed);
                            }
                            info = AuthCommand.Send(this, auth.Message);

                            if ((int)info.StatusCode == 235)
                            {
                                _authenticationModules[i].CloseContext(this);
                                _isConnected = true;
                                return;
                            }
                        }
                    }
                }
            }

            _isConnected = true;
        }