Exemplo n.º 1
0
        /// <summary>
        /// Ends the current client connection.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        private void EndConnection(Imap4SslProxyConnection 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();
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Unknown command received.
 /// </summary>
 /// <param name="sender">The current server to client connection channel.</param>
 private void Unknown(Imap4SslProxyConnection 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, sender.Prefix + " LOGOUT");
     }
 }
Exemplo n.º 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(Imap4SslProxyConnection sender, string data)
        {
            try
            {
                // Add custom validation here.
                // Get the current data.
                string dataArray    = data.Trim();
                string userPassword = string.Empty;
                string prefix       = string.Empty;

                // Start and end of the login index.
                int start = dataArray.ToUpper().IndexOf("LOGIN") + 5;
                userPassword = dataArray.Substring(start);

                // Get the prefix of the current
                // message request.
                int endPrefix = dataArray.IndexOf(" ");
                prefix = dataArray.Substring(0, endPrefix).Trim();

                // Get the user name and passord
                // of the client creadentials.
                sender.ConnectionName = userPassword;
                sender.Prefix         = prefix;
                sender.Connected      = true;

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

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

                // Reply to client internal server error command.
                ReplyToSender(sender, "500 Error");
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Disconnect the client from the server, close the channel.
        /// </summary>
        /// <param name="sender">The current server to client connection channel.</param>
        /// <param name="data">The data from the client.</param>
        private void Disconnect(Imap4SslProxyConnection sender, string data)
        {
            // Add custom validation here.
            // Get the current data.
            string dataArray = data.Trim();
            string prefix    = string.Empty;

            // Get the prefix of the current
            // message request.
            int endPrefix = dataArray.IndexOf(" ");

            prefix        = dataArray.Substring(0, endPrefix).Trim();
            sender.Prefix = prefix;

            // Disconnect the client.
            sender.Connected = false;
            sender.Disconnect(data);
            sender = null;
        }
Exemplo n.º 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(Imap4SslProxyConnection sender, string command)
 {
     sender.SendCommand(command);
 }
Exemplo n.º 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(Imap4SslProxyConnection 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("LOGOUT") > -1)
                {
                    command = "LOGOUT";
                }
                else if (receivedData.ToUpper().IndexOf("LOGIN") > -1)
                {
                    command = "LOGIN";
                }
                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 "LOGOUT":
                    // Close the client connection.
                    Disconnect(sender, receivedData);
                    break;

                case "LOGIN":
                    // User name.
                    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("Imap4SslProxyServer", "client_OnDataReceived", e.Message,
                           292, WriteTo.EventLog, LogType.Error);

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

                // 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 Imap4SslProxyConnection(_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 SslProxyImap4ReceiveHandler(client_OnDataReceived);

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

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

                _listener = null;
            }
        }