Пример #1
0
 internal void ParseExtensions(string[] extensions)
 {
     _supportedAuth = SupportedAuth.None;
     foreach (string extension in extensions)
     {
         if (string.Compare(extension, 0, AuthExtension, 0,
             SizeOfAuthExtension, StringComparison.OrdinalIgnoreCase) == 0)
         {
             // remove the AUTH text including the following character 
             // to ensure that split only gets the modules supported
             string[] authTypes = extension.Remove(0, SizeOfAuthExtension).Split(s_authExtensionSplitters, StringSplitOptions.RemoveEmptyEntries);
             foreach (string authType in authTypes)
             {
                 if (string.Equals(authType, AuthLogin, StringComparison.OrdinalIgnoreCase))
                 {
                     _supportedAuth |= SupportedAuth.Login;
                 }
             }
         }
         else if (string.Compare(extension, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _dsnEnabled = true;
         }
         else if (string.Compare(extension, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _serverSupportsStartTls = true;
         }
         else if (string.Compare(extension, 0, "SMTPUTF8", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _serverSupportsEai = true;
         }
     }
 }
Пример #2
0
 internal void ParseExtensions(string[] extensions)
 {
     _supportedAuth = SupportedAuth.None;
     foreach (string extension in extensions)
     {
         if (string.Compare(extension, 0, authExtension, 0,
                            sizeOfAuthExtension, StringComparison.OrdinalIgnoreCase) == 0)
         {
             // remove the AUTH text including the following character
             // to ensure that split only gets the modules supported
             string[] authTypes = extension.Remove(0, sizeOfAuthExtension).Split(s_authExtensionSplitters, StringSplitOptions.RemoveEmptyEntries);
             foreach (string authType in authTypes)
             {
                 if (string.Equals(authType, authLogin, StringComparison.OrdinalIgnoreCase))
                 {
                     _supportedAuth |= SupportedAuth.Login;
                 }
             }
         }
         else if (string.Compare(extension, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _dsnEnabled = true;
         }
         else if (string.Compare(extension, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _serverSupportsStartTls = true;
         }
         else if (string.Compare(extension, 0, "SMTPUTF8", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             _serverSupportsEai = true;
         }
     }
 }
Пример #3
0
        internal void ParseExtensions(string[] extensions)
        {
            supportedAuth = SupportedAuth.None;
            foreach (string extension in extensions)
            {
                if (String.Compare(extension, 0, authExtension, 0,
                                   sizeOfAuthExtension, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // remove the AUTH text including the following character
                    // to ensure that split only gets the modules supported
                    string[] authTypes =
                        extension.Remove(0, sizeOfAuthExtension).Split(new char[] { ' ', '=' },
                                                                       StringSplitOptions.RemoveEmptyEntries);
                    foreach (string authType in authTypes)
                    {
                        if (String.Compare(authType, authLogin, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            supportedAuth |= SupportedAuth.Login;
                        }
#if !FEATURE_PAL
                        else if (String.Compare(authType, authNtlm, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            supportedAuth |= SupportedAuth.NTLM;
                        }
                        else if (String.Compare(authType, authGssapi, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            supportedAuth |= SupportedAuth.GSSAPI;
                        }
                        else if (String.Compare(authType, authWDigest, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            supportedAuth |= SupportedAuth.WDigest;
                        }
#endif // FEATURE_PAL
                    }
                }
                else if (String.Compare(extension, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    ((SmtpPooledStream)pooledStream).dsnEnabled = true;
                }
                else if (String.Compare(extension, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    serverSupportsStartTls = true;
                }
                else if (String.Compare(extension, 0, "SMTPUTF8", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    ((SmtpPooledStream)pooledStream).serverSupportsEai = true;
                }
            }
        }
 internal void ParseExtensions(string[] extensions)
 {
     this.supportedAuth = SupportedAuth.None;
     foreach (string str in extensions)
     {
         if (string.Compare(str, 0, "auth", 0, 4, StringComparison.OrdinalIgnoreCase) == 0)
         {
             foreach (string str2 in str.Remove(0, 4).Split(new char[] { ' ', '=' }, StringSplitOptions.RemoveEmptyEntries))
             {
                 if (string.Compare(str2, "login", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.Login;
                 }
                 else if (string.Compare(str2, "ntlm", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.NTLM;
                 }
                 else if (string.Compare(str2, "gssapi", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.GSSAPI;
                 }
                 else if (string.Compare(str2, "wdigest", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.WDigest;
                 }
             }
         }
         else if (string.Compare(str, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0)
         {
             ((SmtpPooledStream)this.pooledStream).dsnEnabled = true;
         }
         else if (string.Compare(str, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             this.serverSupportsStartTls = true;
         }
     }
 }
        internal void GetConnection(ServicePoint servicePoint)
        {
            if (this.isConnected)
            {
                throw new InvalidOperationException(SR.GetString("SmtpAlreadyConnected"));
            }
            if (Logging.On)
            {
                Logging.Associate(Logging.Web, this, servicePoint);
            }
            this.connectionPool = ConnectionPoolManager.GetConnectionPool(servicePoint, "", m_CreateConnectionCallback);
            PooledStream pooledStream = this.connectionPool.GetConnection(this, null, this.Timeout);

            while ((((SmtpPooledStream)pooledStream).creds != null) && (((SmtpPooledStream)pooledStream).creds != this.credentials))
            {
                this.connectionPool.PutConnection(pooledStream, pooledStream.Owner, this.Timeout, false);
                pooledStream = this.connectionPool.GetConnection(this, null, this.Timeout);
            }
            if (Logging.On)
            {
                Logging.Associate(Logging.Web, this, pooledStream);
            }
            lock (this)
            {
                this.pooledStream = pooledStream;
            }
            ((SmtpPooledStream)pooledStream).creds = this.credentials;
            this.responseReader = new SmtpReplyReaderFactory(pooledStream.NetworkStream);
            pooledStream.UpdateLifetime();
            if (((SmtpPooledStream)pooledStream).previouslyUsed)
            {
                this.isConnected = true;
            }
            else
            {
                LineInfo info = this.responseReader.GetNextReplyReader().ReadLine();
                if (info.StatusCode != SmtpStatusCode.ServiceReady)
                {
                    throw new SmtpException(info.StatusCode, info.Line, true);
                }
                try
                {
                    this.extensions = EHelloCommand.Send(this, this.client.clientDomain);
                    this.ParseExtensions(this.extensions);
                }
                catch (SmtpException exception)
                {
                    if ((exception.StatusCode != SmtpStatusCode.CommandUnrecognized) && (exception.StatusCode != SmtpStatusCode.CommandNotImplemented))
                    {
                        throw exception;
                    }
                    HelloCommand.Send(this, this.client.clientDomain);
                    this.supportedAuth = SupportedAuth.Login;
                }
                if (this.enableSsl)
                {
                    if (!this.serverSupportsStartTls && !(pooledStream.NetworkStream is TlsStream))
                    {
                        throw new SmtpException(SR.GetString("MailServerDoesNotSupportStartTls"));
                    }
                    StartTlsCommand.Send(this);
                    TlsStream stream2 = new TlsStream(servicePoint.Host, pooledStream.NetworkStream, this.clientCertificates, servicePoint, this.client, null);
                    pooledStream.NetworkStream = stream2;
                    this.channelBindingToken   = stream2.GetChannelBinding(ChannelBindingKind.Unique);
                    this.responseReader        = new SmtpReplyReaderFactory(pooledStream.NetworkStream);
                    this.extensions            = EHelloCommand.Send(this, this.client.clientDomain);
                    this.ParseExtensions(this.extensions);
                }
                if (this.credentials != null)
                {
                    for (int i = 0; i < this.authenticationModules.Length; i++)
                    {
                        Authorization authorization;
                        if (this.AuthSupported(this.authenticationModules[i]))
                        {
                            NetworkCredential credential = this.credentials.GetCredential(servicePoint.Host, servicePoint.Port, this.authenticationModules[i].AuthenticationType);
                            if (credential != null)
                            {
                                authorization = this.SetContextAndTryAuthenticate(this.authenticationModules[i], credential, null);
                                if ((authorization != null) && (authorization.Message != null))
                                {
                                    info = AuthCommand.Send(this, this.authenticationModules[i].AuthenticationType, authorization.Message);
                                    if (info.StatusCode != SmtpStatusCode.CommandParameterNotImplemented)
                                    {
                                        goto Label_0363;
                                    }
                                }
                            }
                        }
                        continue;
Label_02F2:
                        authorization = this.authenticationModules[i].Authenticate(info.Line, null, this, this.client.TargetName, this.channelBindingToken);
                        if (authorization == null)
                        {
                            throw new SmtpException(SR.GetString("SmtpAuthenticationFailed"));
                        }
                        info = AuthCommand.Send(this, authorization.Message);
                        if (info.StatusCode == ((SmtpStatusCode)0xeb))
                        {
                            this.authenticationModules[i].CloseContext(this);
                            this.isConnected = true;
                            return;
                        }
Label_0363:
                        if (info.StatusCode == ((SmtpStatusCode)0x14e))
                        {
                            goto Label_02F2;
                        }
                    }
                }
                this.isConnected = true;
            }
        }
Пример #6
0
        internal void GetConnection(string host, int port)
        {
            if (_isConnected)
            {
                throw new InvalidOperationException(SR.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 e;
                }

                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(SR.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(SR.SmtpAuthenticationFailed);
                            }
                            info = AuthCommand.Send(this, auth.Message);

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

            _isConnected = true;
        }
Пример #7
0
        internal void GetConnection(ServicePoint servicePoint)
        {
            if (isConnected)
            {
                throw new InvalidOperationException(SR.GetString(SR.SmtpAlreadyConnected));
            }

            if (Logging.On)
            {
                Logging.Associate(Logging.Web, this, servicePoint);
            }
            Debug.Assert(servicePoint != null, "servicePoint was null from SmtpTransport");
            connectionPool = ConnectionPoolManager.GetConnectionPool(servicePoint, "", m_CreateConnectionCallback);

            PooledStream pooledStream = connectionPool.GetConnection((object)this, null, Timeout);

            while (((SmtpPooledStream)pooledStream).creds != null && ((SmtpPooledStream)pooledStream).creds != credentials)
            {
                // destroy this connection so that a new connection can be created
                // in order to use the proper credentials.  Do not just close the
                // connection since it's in a state where a QUIT could be sent
                connectionPool.PutConnection(pooledStream, pooledStream.Owner, Timeout, false);
                pooledStream = connectionPool.GetConnection((object)this, null, Timeout);
            }
            if (Logging.On)
            {
                Logging.Associate(Logging.Web, this, pooledStream);
            }

            lock (this) {
                this.pooledStream = pooledStream;
            }

            ((SmtpPooledStream)pooledStream).creds = credentials;

            responseReader = new SmtpReplyReaderFactory(pooledStream.NetworkStream);

            //set connectionlease
            pooledStream.UpdateLifetime();

            //if the stream was already used, then we've already done the handshake
            if (((SmtpPooledStream)pooledStream).previouslyUsed == true)
            {
                isConnected = true;
                return;
            }

            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 e;
                }

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

#if !FEATURE_PAL
            // Establish TLS
            if (enableSsl)
            {
                if (!serverSupportsStartTls)
                {
                    // Either TLS is already established or server does not support TLS
                    if (!(pooledStream.NetworkStream is TlsStream))
                    {
                        throw new SmtpException(SR.GetString(SR.MailServerDoesNotSupportStartTls));
                    }
                }
                StartTlsCommand.Send(this);
                TlsStream TlsStream = new TlsStream(servicePoint.Host, pooledStream.NetworkStream, clientCertificates, servicePoint, client, null);

                pooledStream.NetworkStream = TlsStream;

                //for SMTP, the CBT should be unique
                this.channelBindingToken = TlsStream.GetChannelBinding(ChannelBindingKind.Unique);

                responseReader = new SmtpReplyReaderFactory(pooledStream.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);
            }
#endif // !FEATURE_PAL

            //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  - [....]
                    if (!AuthSupported(authenticationModules[i]))
                    {
                        continue;
                    }

                    NetworkCredential credential = credentials.GetCredential(servicePoint.Host,
                                                                             servicePoint.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, this.client.TargetName, this.channelBindingToken);
                            if (auth == null)
                            {
                                throw new SmtpException(SR.GetString(SR.SmtpAuthenticationFailed));
                            }
                            info = AuthCommand.Send(this, auth.Message);

                            if ((int)info.StatusCode == 235)
                            {
                                authenticationModules[i].CloseContext(this);
                                isConnected = true;
                                return;
                            }
                        }
                    }
                }
            }
            isConnected = true;
        }
 internal void ParseExtensions(string[] extensions)
 {
     this.supportedAuth = SupportedAuth.None;
     foreach (string str in extensions)
     {
         if (string.Compare(str, 0, "auth", 0, 4, StringComparison.OrdinalIgnoreCase) == 0)
         {
             foreach (string str2 in str.Remove(0, 4).Split(new char[] { ' ', '=' }, StringSplitOptions.RemoveEmptyEntries))
             {
                 if (string.Compare(str2, "login", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.Login;
                 }
                 else if (string.Compare(str2, "ntlm", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.NTLM;
                 }
                 else if (string.Compare(str2, "gssapi", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.GSSAPI;
                 }
                 else if (string.Compare(str2, "wdigest", StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     this.supportedAuth |= SupportedAuth.WDigest;
                 }
             }
         }
         else if (string.Compare(str, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0)
         {
             ((SmtpPooledStream) this.pooledStream).dsnEnabled = true;
         }
         else if (string.Compare(str, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
         {
             this.serverSupportsStartTls = true;
         }
     }
 }
 internal void GetConnection(ServicePoint servicePoint)
 {
     if (this.isConnected)
     {
         throw new InvalidOperationException(SR.GetString("SmtpAlreadyConnected"));
     }
     if (Logging.On)
     {
         Logging.Associate(Logging.Web, this, servicePoint);
     }
     this.connectionPool = ConnectionPoolManager.GetConnectionPool(servicePoint, "", m_CreateConnectionCallback);
     PooledStream pooledStream = this.connectionPool.GetConnection(this, null, this.Timeout);
     while ((((SmtpPooledStream) pooledStream).creds != null) && (((SmtpPooledStream) pooledStream).creds != this.credentials))
     {
         this.connectionPool.PutConnection(pooledStream, pooledStream.Owner, this.Timeout, false);
         pooledStream = this.connectionPool.GetConnection(this, null, this.Timeout);
     }
     if (Logging.On)
     {
         Logging.Associate(Logging.Web, this, pooledStream);
     }
     lock (this)
     {
         this.pooledStream = pooledStream;
     }
     ((SmtpPooledStream) pooledStream).creds = this.credentials;
     this.responseReader = new SmtpReplyReaderFactory(pooledStream.NetworkStream);
     pooledStream.UpdateLifetime();
     if (((SmtpPooledStream) pooledStream).previouslyUsed)
     {
         this.isConnected = true;
     }
     else
     {
         LineInfo info = this.responseReader.GetNextReplyReader().ReadLine();
         if (info.StatusCode != SmtpStatusCode.ServiceReady)
         {
             throw new SmtpException(info.StatusCode, info.Line, true);
         }
         try
         {
             this.extensions = EHelloCommand.Send(this, this.client.clientDomain);
             this.ParseExtensions(this.extensions);
         }
         catch (SmtpException exception)
         {
             if ((exception.StatusCode != SmtpStatusCode.CommandUnrecognized) && (exception.StatusCode != SmtpStatusCode.CommandNotImplemented))
             {
                 throw exception;
             }
             HelloCommand.Send(this, this.client.clientDomain);
             this.supportedAuth = SupportedAuth.Login;
         }
         if (this.enableSsl)
         {
             if (!this.serverSupportsStartTls && !(pooledStream.NetworkStream is TlsStream))
             {
                 throw new SmtpException(SR.GetString("MailServerDoesNotSupportStartTls"));
             }
             StartTlsCommand.Send(this);
             TlsStream stream2 = new TlsStream(servicePoint.Host, pooledStream.NetworkStream, this.clientCertificates, servicePoint, this.client, null);
             pooledStream.NetworkStream = stream2;
             this.channelBindingToken = stream2.GetChannelBinding(ChannelBindingKind.Unique);
             this.responseReader = new SmtpReplyReaderFactory(pooledStream.NetworkStream);
             this.extensions = EHelloCommand.Send(this, this.client.clientDomain);
             this.ParseExtensions(this.extensions);
         }
         if (this.credentials != null)
         {
             for (int i = 0; i < this.authenticationModules.Length; i++)
             {
                 Authorization authorization;
                 if (this.AuthSupported(this.authenticationModules[i]))
                 {
                     NetworkCredential credential = this.credentials.GetCredential(servicePoint.Host, servicePoint.Port, this.authenticationModules[i].AuthenticationType);
                     if (credential != null)
                     {
                         authorization = this.SetContextAndTryAuthenticate(this.authenticationModules[i], credential, null);
                         if ((authorization != null) && (authorization.Message != null))
                         {
                             info = AuthCommand.Send(this, this.authenticationModules[i].AuthenticationType, authorization.Message);
                             if (info.StatusCode != SmtpStatusCode.CommandParameterNotImplemented)
                             {
                                 goto Label_0363;
                             }
                         }
                     }
                 }
                 continue;
             Label_02F2:
                 authorization = this.authenticationModules[i].Authenticate(info.Line, null, this, this.client.TargetName, this.channelBindingToken);
                 if (authorization == null)
                 {
                     throw new SmtpException(SR.GetString("SmtpAuthenticationFailed"));
                 }
                 info = AuthCommand.Send(this, authorization.Message);
                 if (info.StatusCode == ((SmtpStatusCode) 0xeb))
                 {
                     this.authenticationModules[i].CloseContext(this);
                     this.isConnected = true;
                     return;
                 }
             Label_0363:
                 if (info.StatusCode == ((SmtpStatusCode) 0x14e))
                 {
                     goto Label_02F2;
                 }
             }
         }
         this.isConnected = true;
     }
 }
Пример #10
0
        internal void GetConnection(ServicePoint servicePoint)
        {
            if (isConnected)
            {
                throw new InvalidOperationException(SR.GetString(SR.SmtpAlreadyConnected));
            }

            if (Logging.On) Logging.Associate(Logging.Web, this, servicePoint);
            Debug.Assert(servicePoint != null, "servicePoint was null from SmtpTransport");
            connectionPool = ConnectionPoolManager.GetConnectionPool(servicePoint, "", m_CreateConnectionCallback);

            PooledStream pooledStream = connectionPool.GetConnection((object)this, null, Timeout);

            while (((SmtpPooledStream)pooledStream).creds != null && ((SmtpPooledStream)pooledStream).creds != credentials) {
                // destroy this connection so that a new connection can be created 
                // in order to use the proper credentials.  Do not just close the 
                // connection since it's in a state where a QUIT could be sent
                connectionPool.PutConnection(pooledStream, pooledStream.Owner, Timeout, false);
                pooledStream = connectionPool.GetConnection((object)this, null, Timeout);
            }
            if (Logging.On) Logging.Associate(Logging.Web, this, pooledStream);

            lock (this) {
                this.pooledStream = pooledStream;
            }

            ((SmtpPooledStream)pooledStream).creds = credentials;

            responseReader = new SmtpReplyReaderFactory(pooledStream.NetworkStream);

            //set connectionlease
            pooledStream.UpdateLifetime();

            //if the stream was already used, then we've already done the handshake
            if (((SmtpPooledStream)pooledStream).previouslyUsed == true) {
                isConnected = true;
                return;
            }

            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 e;
                }

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

#if !FEATURE_PAL
            // Establish TLS
            if (enableSsl) 
            {
                if (!serverSupportsStartTls) 
                {
                    // Either TLS is already established or server does not support TLS
                    if (!(pooledStream.NetworkStream is TlsStream)) 
                    {
                        throw new SmtpException(SR.GetString(SR.MailServerDoesNotSupportStartTls));
                    }
                }
                StartTlsCommand.Send(this);
                TlsStream TlsStream = new TlsStream(servicePoint.Host, pooledStream.NetworkStream, clientCertificates, servicePoint, client, null);

                pooledStream.NetworkStream = TlsStream;

                //for SMTP, the CBT should be unique
                this.channelBindingToken = TlsStream.GetChannelBinding(ChannelBindingKind.Unique);

                responseReader = new SmtpReplyReaderFactory(pooledStream.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);
            }
#endif // !FEATURE_PAL

            //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  - [....]
                    if (!AuthSupported(authenticationModules[i])) {
                        continue;
                    }

                    NetworkCredential credential = credentials.GetCredential(servicePoint.Host, 
                        servicePoint.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, this.client.TargetName, this.channelBindingToken);
                            if (auth == null)
                            {
                                throw new SmtpException(SR.GetString(SR.SmtpAuthenticationFailed));
                            }
                            info = AuthCommand.Send(this, auth.Message);

                            if ((int)info.StatusCode == 235)
                            {
                                authenticationModules[i].CloseContext(this);
                                isConnected = true;
                                return;
                            }
                        }
                    }
                }
            }
            isConnected = true;
        }
Пример #11
0
        internal void ParseExtensions(string[] extensions) {
            supportedAuth = SupportedAuth.None;
            foreach (string extension in extensions) {
                if (String.Compare(extension, 0, authExtension, 0, 
                    sizeOfAuthExtension, StringComparison.OrdinalIgnoreCase) == 0)  {
                    // remove the AUTH text including the following character 
                    // to ensure that split only gets the modules supported
                    string[] authTypes = 
                        extension.Remove(0, sizeOfAuthExtension).Split(new char[] { ' ', '=' },
                        StringSplitOptions.RemoveEmptyEntries);
                    foreach (string authType in authTypes) {
                        if (String.Compare(authType, authLogin, StringComparison.OrdinalIgnoreCase) == 0) {
                            supportedAuth |= SupportedAuth.Login;
                        }
#if !FEATURE_PAL
                        else if (String.Compare(authType, authNtlm, StringComparison.OrdinalIgnoreCase) == 0) {
                            supportedAuth |= SupportedAuth.NTLM;
                        }
                        else if (String.Compare(authType, authGssapi, StringComparison.OrdinalIgnoreCase) == 0) {
                            supportedAuth |= SupportedAuth.GSSAPI;
                        }
                        else if (String.Compare(authType, authWDigest, StringComparison.OrdinalIgnoreCase) == 0) {
                            supportedAuth |= SupportedAuth.WDigest;
                        }
#endif // FEATURE_PAL
                    }
                }
                else if (String.Compare(extension, 0, "dsn ", 0, 3, StringComparison.OrdinalIgnoreCase) == 0) {
                    ((SmtpPooledStream)pooledStream).dsnEnabled = true;
                }
                else if (String.Compare(extension, 0, "STARTTLS", 0, 8, StringComparison.OrdinalIgnoreCase) == 0) {
                    serverSupportsStartTls = true;
                }
                else if (String.Compare(extension, 0, "SMTPUTF8", 0, 8, StringComparison.OrdinalIgnoreCase) == 0) {
                    ((SmtpPooledStream)pooledStream).serverSupportsEai = true;
                }
            }
        }
Пример #12
0
        internal void GetConnection(string host, int port)
        {
            if (_isConnected)
            {
                throw new InvalidOperationException(SR.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 e;
                }

                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(SR.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(SR.SmtpAuthenticationFailed);
                            }
                            info = AuthCommand.Send(this, auth.Message);

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

            _isConnected = true;
        }