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