Пример #1
0
        /// <summary>
        /// Request an ssl connection 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 SslConnection(Pop3TlsProxyConnection sender, string data)
        {
            try
            {
                // Create an ssl connection from the socket.
                // Reply to the client that a ssl connection
                // is being created.
                sender.InitializingSSLConnection("OK Begin TLS negotiation now");
                sender.TlsNegotiated = true;
            }
            catch (Exception e)
            {
                // Detect a thread abort exception.
                if (e is ThreadAbortException)
                {
                    Thread.ResetAbort();
                }

                base.Write("Pop3TlsProxyServer", "SslConnection", e.Message,
                           382, WriteTo.EventLog, LogType.Error);

                // Reply to client internal server error command.
                ReplyToSender(sender, "500 -ERROR");
            }
        }
Пример #2
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>
        /// <param name="command">The command sent.</param>
        private void Connect(Pop3TlsProxyConnection sender, string data, string command)
        {
            try
            {
                // Is the command user.
                if (command.Equals("USER"))
                {
                    sender.ConnectionName = data;
                }

                // Is the command pass then connected
                if (command.Equals("PASS"))
                {
                    sender.Connected = true;
                }

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

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

                // Reply to client internal server error command.
                ReplyToSender(sender, "500 Error");
            }
        }
Пример #3
0
        /// <summary>
        /// Ends the current client connection.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        private void EndConnection(Pop3TlsProxyConnection 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();
            }
        }
Пример #4
0
 /// <summary>
 /// Unknown command received.
 /// </summary>
 /// <param name="sender">The current server to client connection channel.</param>
 private void Unknown(Pop3TlsProxyConnection 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);
     }
 }
Пример #5
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(Pop3TlsProxyConnection sender)
 {
     sender.Connected = false;
     sender.Disconnect();
     sender = null;
 }
Пример #6
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(Pop3TlsProxyConnection sender, string command)
 {
     sender.SendCommand(command);
 }
Пример #7
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(Pop3TlsProxyConnection 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("QUIT") > -1)
                {
                    command = "QUIT";
                }
                else if (receivedData.ToUpper().IndexOf("USER") > -1)
                {
                    command = "USER";
                }
                else if (receivedData.ToUpper().IndexOf("STARTTLS") > -1)
                {
                    command = "STARTTLS";
                }
                else if (receivedData.ToUpper().IndexOf("CAPABILITY") > -1)
                {
                    command = "CAPABILITY";
                }
                else if (receivedData.ToUpper().IndexOf("PASS") > -1)
                {
                    command = "PASS";
                }
                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, command);
                    break;

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

                case "CAPABILITY":
                    if (!sender.TlsNegotiated)
                    {
                        sender.SendNonSSLClientCommand("* CAPABILITY POP3 STARTTLS LOGINDISABLED");
                        sender.SendNonSSLClientCommand("OK CAPABILITY completed");
                    }
                    else
                    {
                        // Send the command to the pop3 server.
                        sender.SendSocketCommand(receivedData);
                    }

                    break;

                case "STARTTLS":
                    // Start a TLS connection.
                    SslConnection(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("Pop3TlsProxyServer", "OnDataReceived", e.Message,
                           292, WriteTo.EventLog, LogType.Error);

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

                // 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 Pop3TlsProxyConnection(_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 TlsProxyPop3ReceiveHandler(client_OnDataReceived);

                        // Increment the count.
                        Interlocked.Increment(ref _clientCount);
                    }
                    else
                    {
                        base.Write("Pop3TlsProxyServer", "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("Pop3TlsProxyServer", "StartListen", see.Message,
                           121, WriteTo.EventLog, LogType.Error);
            }
            catch (Exception e)
            {
                // Detect a thread abort exception.
                if (e is ThreadAbortException)
                {
                    Thread.ResetAbort();
                }

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

                _listener = null;
            }
        }