Beispiel #1
0
        /// <summary>
        /// Ends the current client connection.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        private void EndConnection(SmtpSslProxyConnection sender)
        {
            // Release the current client connection
            // resources and make avaliable a new connection.
            if (_client[sender.ClientIndex] != null)
            {
                _client[sender.ClientIndex].Dispose();
                _client[sender.ClientIndex] = null;

                // Decrement the count.
                Interlocked.Decrement(ref _clientCount);

                // Signal to the blocking handler
                // to un-block.
                _connAvailable.Set();
            }
        }
Beispiel #2
0
 /// <summary>
 /// Unknown command received.
 /// </summary>
 /// <param name="sender">The current server to client connection channel.</param>
 private void Unknown(SmtpSslProxyConnection sender)
 {
     if (sender.Connected)
     {
         // Reply to client with unknown command.
         ReplyToSender(sender, "-ERR Unknown command");
     }
     else
     {
         // If an unknown command is sent when the channel is opened
         // but the user has not supplied valid credentials then close
         // the socket channel to the client. This is needed when a
         // client opens a socket channel and starts sending a DOS
         // attack.
         Disconnect(sender);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Connect the client to the server.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        /// <param name="data">The data from the client.</param>
        private void Connect(SmtpSslProxyConnection sender, string data)
        {
            try
            {
                // Add custom validation here.
                // Get the current data.
                string dataArray = data.Trim();

                // Is the command user.
                if (data.ToUpper().IndexOf("USER") > -1)
                {
                    sender.ConnectionName = dataArray;
                }

                // Is the command pass then connected
                if (data.ToUpper().IndexOf("PASS") > -1)
                {
                    sender.Connected = true;
                }

                // Send the command to the smtp server.
                sender.SendSocketCommand(data);
            }
            catch (Exception e)
            {
                // Detect a thread abort exception.
                if (e is ThreadAbortException)
                {
                    Thread.ResetAbort();
                }

                base.Write("SmtpSslProxyServer", "Connect", e.Message,
                           382, WriteTo.EventLog, LogType.Error);

                // Reply to client internal server error command.
                ReplyToSender(sender, "500 Error");
            }
        }
Beispiel #4
0
 /// <summary>
 /// Disconnect the client from the server, close the channel.
 /// </summary>
 /// <param name="sender">The current server to client connection channel.</param>
 private void Disconnect(SmtpSslProxyConnection sender)
 {
     sender.Connected = false;
     sender.Disconnect();
     sender = null;
 }
Beispiel #5
0
 /// <summary>
 /// Reply to the current client.
 /// </summary>
 /// <param name="sender">The current server to client connection channel.</param>
 /// <param name="command">The command to send to the client.</param>
 private void ReplyToSender(SmtpSslProxyConnection sender, string command)
 {
     sender.SendCommand(command);
 }
Beispiel #6
0
        /// <summary>
        /// Processes all in-comming client command requests.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        /// <param name="dataReceived">The data received from the client.</param>
        private void client_OnDataReceived(SmtpSslProxyConnection sender, string dataReceived)
        {
            try
            {
                // Decrypt the data recived from the client.
                string receivedData = dataReceived.Trim();
                string command      = string.Empty;

                // Get specific commands from the client.
                if (receivedData.ToUpper().IndexOf("USER") > -1)
                {
                    command = "USER";
                }
                else if (receivedData.ToUpper().IndexOf("PASS") > -1)
                {
                    command = "PASS";
                }
                else if (receivedData.ToUpper().IndexOf("QUIT") > -1)
                {
                    command = "QUIT";
                }
                else if (receivedData.ToUpper().IndexOf("ENDC") > -1)
                {
                    command = "ENDC";
                }
                else
                {
                    command = receivedData;
                }

                // Delay.
                System.Threading.Thread.Sleep(10);

                // Process the command.
                switch (command.ToUpper())
                {
                //case "QUIT":
                //    // Close the client connection.
                //    Disconnect(sender);
                //    break;

                case "USER":
                    // User name.
                    Connect(sender, receivedData);
                    break;

                case "PASS":
                    // User password.
                    Connect(sender, receivedData);
                    break;

                //case "ENDC":
                //    // End the client connection.
                //    EndConnection(sender);
                //    break;

                default:
                    // An unknown command sent.
                    //Unknown(sender);
                    sender.SendSocketCommand(receivedData);
                    break;
                }
            }
            catch (Exception e)
            {
                // Detect a thread abort exception.
                if (e is ThreadAbortException)
                {
                    Thread.ResetAbort();
                }

                base.Write("SmtpSslProxyServer", "OnDataReceived", e.Message,
                           292, WriteTo.EventLog, LogType.Error);

                // Reply to client internal server error command.
                ReplyToSender(sender, "500 Error");
            }
        }
Beispiel #7
0
        /// <summary>
        /// Starts listening on the specified port.
        /// </summary>
        public void StartListen()
        {
            try
            {
                // Get the smtp server information from
                // the configuration file, the host and
                // port of the smtp server is located in
                // the default section, this data is used
                // to connect to the smtp server.
                GetSmtpServerHost();

                // Get the listening port from the configuration
                // file, if no port specified then default or
                // the current port set will be used.
                GetListeningPort();

                // Get the maximum number of clients from the configuration
                // file, if no value is specified then default or
                // the current value will be used.
                GetMaxNumClients();

                // Get the client idle time out from the configuration
                // file, if no value is specified then default or
                // the current value will be used.
                GetClientTimeOut();

                // Get the local end point, the server will listen
                // on only the first IP address assigned.
                //IPEndPoint endPoint = new IPEndPoint(Dns.GetHostEntry(remoteHost).AddressList[0], listenPort);

                // Create a new tcp listener server,
                // and start the server.
                _listener = new TcpListener(System.Net.IPAddress.Any, _listenPort);
                _listener.Start();

                // While the server is alive accept in-comming client
                // connections.
                do
                {
                    // Do not allow any more clients
                    // if maximum is reached.
                    if (_clientCount < (_maxNumClients - 1))
                    {
                        // Find the next available
                        // connection within the list.
                        for (int i = 0; i < _client.Count(); i++)
                        {
                            if (_client[i] == null)
                            {
                                _clientIndex = i;
                                break;
                            }
                        }

                        // Create a new client connection handler for the current
                        // tcp client attempting to connect to the server. Creates
                        // a new channel from the client to the server.
                        _client[_clientIndex] =
                            new SmtpSslProxyConnection(_listener.AcceptTcpClient(), _connection);

                        // Assign the current index.
                        _client[_clientIndex].ClientIndex = _clientIndex;

                        // if a time out has been set.
                        if (_timeOut > 0)
                        {
                            _client[_clientIndex].TimeOut = _timeOut;
                        }

                        // Create a new client data receive handler, this event
                        // handles commands from the current client.
                        _client[_clientIndex].OnDataReceived +=
                            new SslProxySmtpReceiveHandler(client_OnDataReceived);

                        // Increment the count.
                        Interlocked.Increment(ref _clientCount);
                    }
                    else
                    {
                        base.Write("SslProxySmtpHost", "StartListen", "Maximum number of client connections has been reached.",
                                   120, WriteTo.EventLog, LogType.Error);

                        // Blocks the current thread until a
                        // connection becomes available.
                        _connAvailable.WaitOne();
                    }
                } while (true);
            }
            catch (SocketException see)
            {
                base.Write("SmtpSslProxyServer", "StartListen", see.Message,
                           121, WriteTo.EventLog, LogType.Error);
            }
            catch (Exception e)
            {
                // Detect a thread abort exception.
                if (e is ThreadAbortException)
                {
                    Thread.ResetAbort();
                }

                base.Write("SmtpSslProxyServer", "StartListen", e.Message,
                           121, WriteTo.EventLog, LogType.Error);
            }
            finally
            {
                if (_listener != null)
                {
                    _listener.Stop();
                }

                _listener = null;
            }
        }