private void EndResolve() { if (State != ClientState.Disconnected) { try { _hostEntry = Dns.EndResolve(_currentAsyncResult); } catch (Exception e) { if (!HandleException(e)) { throw new AsyncTcpClientException(this, e); } OnResolveFailed(); return; } try { State = ClientState.Connecting; _socket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (_ssl3Enabled) { _socket.ChangeSecurityProtocol(new SecurityOptions(SecureProtocol.Ssl3)); } _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, Timeout); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, Timeout); _endPoint = new IPEndPoint(_hostEntry.AddressList[0], _port); if (_traceProtocol) { Trace("Connecting to " + _endPoint.Address.ToString() + ':' + _endPoint.Port.ToString()); } CloseAsyncWaitHandle(); _currentAsyncResult = _socket.BeginConnect(_endPoint, null, null); InvokeAfterWait(new MethodInvoker(EndConnect), _currentAsyncResult.AsyncWaitHandle); } catch (Exception e) { if (!HandleException(e)) { throw new AsyncTcpClientException(this, e); } OnConnectFailed(); return; } } }
public void Start() { try { // ask the user for SMTP server, port and the type of connection Console.Write("Host to connect to: "); string server = Console.ReadLine().Trim(); Console.Write("Port: "); string port = Console.ReadLine().Trim(); Console.Write("Connection type [0 = normal connection, 1 = direct TLS connection, 2 = indirect TLS connection (using STARTTLS command)]: "); string type = Console.ReadLine().Trim(); if (Array.IndexOf(new string[] { "0", "1", "2" }, type) == -1) { Console.WriteLine("Invalid connection type."); return; } Console.WriteLine("Please enter the email address you wish to send an email to:"); string address = Console.ReadLine().Trim(); // create a new SecurityOptions instance SecurityOptions options = new SecurityOptions(SecureProtocol.None); // allow only secure ciphers to be used. Currently, the seure ciphers are: // the AES algorithm [128 or 256 bit keys], the RC4 algorithm [128 bit keys] // or TipleDES [168 bit keys] options.AllowedAlgorithms = SslAlgorithms.SECURE_CIPHERS; // the SecureSocket should be a client socket options.Entity = ConnectionEnd.Client; // we will use manual verification of the server certificate options.VerificationType = CredentialVerification.Manual; // when the server certificate is receives, the SecureSocket should call // the OnVerify method options.Verifier = new CertVerifyEventHandler(OnVerify); // use the default flags options.Flags = SecurityFlags.Default; // the common name is the domain name or IP address of the server options.CommonName = server; // if the user chose a direct TLS connection, set the protocol to TLS1 if (type == "1") { options.Protocol = SecureProtocol.Tls1; } // create the new secure socket Connection = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, options); // connect to the SMTP server Connection.Connect(new IPEndPoint(Dns.Resolve(server).AddressList[0], int.Parse(port))); // wait for the server hello message if (!IsReplyOK(Receive())) { Console.WriteLine("Server disallowed connection."); return; } // if the user selected an indirect TLS connection, issue // a EHLO command. Otherwise, stick to the standard HELO command. if (type == "2") // STARTTLS connection { Send("EHLO SmtpClient.Mentalis.org\r\n"); } else { Send("HELO SmtpClient.Mentalis.org\r\n"); } if (!IsReplyOK(Receive())) { Console.WriteLine("HELLO failed."); return; } // if the user selected an indirect TLS connection, issue // the STARTTLS command if (type == "2") { // send the STARTTLS command to the server Send("STARTTLS\r\n"); // make sure the server supports the STARTTLS command if (!IsReplyOK(Receive())) { Console.WriteLine("STARTTLS failed."); return; } // change the protocol from SecureProtocol.None // to SecureProtocol.Tls1 options.Protocol = SecureProtocol.Tls1; // start the TLS handshake Connection.ChangeSecurityProtocol(options); // after this line, we're using an encrypted TLS connection } // from here on, act as if the SecureSocket is a normal Socket Send("MAIL FROM: [email protected]\r\n"); // [email protected] is not a real email address if (!IsReplyOK(Receive())) { Console.WriteLine("MAIL FROM failed."); return; } Send("RCPT TO:" + address + "\r\n"); if (!IsReplyOK(Receive())) { Console.WriteLine("RCPT TO failed."); return; } Send("DATA\r\n"); if (!IsReplyOK(Receive())) { Console.WriteLine("DATA failed."); return; } Send(TestMail.Replace("#ADDRESS#", address) + "\r\n.\r\n"); if (!IsReplyOK(Receive())) { Console.WriteLine("Sending of e-mail failed."); return; } Send("QUIT\r\n"); if (!IsReplyOK(Receive())) { Console.WriteLine("QUIT failed."); } Connection.Shutdown(SocketShutdown.Both); } catch (Exception e) { Console.WriteLine("An error occurred [" + e.Message + "]"); Console.WriteLine(e); } finally { if (Connection != null) { Connection.Close(); } } }
private void StartTLS() { SendAndWaitResponse("STARTTLS"); options.Protocol = SecureProtocol.Tls1; connection.ChangeSecurityProtocol(options); }