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