protected static void HandleHeader(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.RawInput == "")
     {
         context._CurrentHandlers = _BodyHandlers;
     }
     else
     {
         context.Message.Headers.Add(input.RawInput);
     }
 }
 protected static void OnMailFrom(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.Params.Length != 2 || input.Params.First().ToUpper() != "FROM:")
     {
         UnknownCommand(context, input);
     }
     else
     {
         context.Message.MailFrom = input.Params.Last();
     }
     context.WriteLine(250, "Ok");
 }
 protected static void HandleBody(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.RawInput == ".")
     {
         context.FireReceieMessage();
         context._CurrentHandlers = _InitialHandlers;
         context.Reset();
         context.WriteLine(250, "Ok");
     }
     else
     {
         context.Message.Data.Add(input.RawInput);
     }
 }
 protected static void OnEHLO(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (context.Server.Credentials.Any())
     {
         context.WriteLine(
             "250-localhost\r\n" +
             "250-AUTH CRAM-MD5\r\n" +
             "250-AUTH LOGIN CRAM-MD5\r\n" +
             "250-AUTH=CRAM-MD5\r\n" +
             "250 AUTH=LOGIN CRAM-MD5");
     }
     else
     {
         context.WriteLine(250, "Ok");
     }
 }
        protected static void OnRcptTo(SmtpServerSession context, SmtpClientInputLine input)
        {
            if (input.Params.Length != 2 || input.Params.First().ToUpper() != "TO:")
            {
                UnknownCommand(context, input);
                return;
            }
            var rcptto = input.Params.Last();

            if (context.Server.Credentials.Any() && context.User.IsAuthenticated == false)
            {
                context.WriteLine(554, "{0}: Recipient address rejected: Access denied", rcptto);
                return;
            }
            context.Message.RcptTo.Add(rcptto);
            context.WriteLine(250, "Ok");
        }
        protected static void AuthCRAMMD5(SmtpServerSession context, SmtpClientInputLine input)
        {
            try
            {
                const string AuthCRAMMD5Key = "AuthCRAMMD5Key";
                context._CurrentHandlers = _AuthCRAMMD5Handlers;
                if (input.Command.ToUpper() == "AUTH")
                {
                    context.ClearIdentity();
                    context.Items[AuthCRAMMD5Key] = Guid.NewGuid().ToByteArray().ToBase64();
                    context.WriteLine(334, context.Items[AuthCRAMMD5Key] as string);
                }
                else
                {
                    var pair = input.RawInput.Base64ToBytes().ToString(Encoding.UTF8).Split(' ');
                    context._User.Name = pair.First();
                    var credential = context.Server
                                     .Credentials
                                     .FirstOrDefault(c => c.UserName == context._User.Name);
                    if (credential == null)
                    {
                        FailAuthentication(context);
                        return;
                    }

                    var hmacmd5str = new HMACMD5(credential.Password.GetBytes())
                                     .ComputeHash(context.Items[AuthCRAMMD5Key].ToString().Base64ToBytes())
                                     .ToHexString();
                    context.Items.Remove(AuthCRAMMD5Key);
                    if (hmacmd5str != pair.Last())
                    {
                        FailAuthentication(context);
                    }
                    else
                    {
                        Authentication(context);
                    }
                }
            }
            catch (FormatException)
            {
                context._CurrentHandlers = _InitialHandlers;
                UnknownCommand(context, input);
            }
        }
 protected static void AuthPlain(SmtpServerSession context, SmtpClientInputLine input)
 {
     try
     {
         context._CurrentHandlers = _AuthPlainHandlers;
         if (input.Command.ToUpper() == "AUTH")
         {
             context.ClearIdentity();
             var user = input.Params.Skip(1).FirstOrDefault() ?? "";
             if (user.IsNullOrEmpty())
             {
                 context.WriteLine(334, "Username:"******"Password:"******"Password:".GetBytes().ToBase64());
         }
         else
         {
             var password = input.RawInput.Base64ToBytes().ToString(Encoding.UTF8);
             var found    = context.Server.Credentials.Any(c => c.UserName == context.User.Name && c.Password == password);
             if (found == false)
             {
                 FailAuthentication(context);
             }
             else
             {
                 Authentication(context);
             }
         }
     }
     catch (FormatException)
     {
         context._CurrentHandlers = _InitialHandlers;
         UnknownCommand(context, input);
     }
 }
        protected static void OnAuth(SmtpServerSession context, SmtpClientInputLine input)
        {
            var loginMethod = input.Params.First();

            switch (loginMethod.ToUpper())
            {
            case "LOGIN":
                AuthPlain(context, input);
                return;

            case "CRAM-MD5":
                AuthCRAMMD5(context, input);
                return;

            default:
                FailAuthentication(context);
                break;
            }
        }
 protected static void FailAuthentication(SmtpServerSession context)
 {
     context.ClearIdentity();
     context._CurrentHandlers = _InitialHandlers;
     context.WriteLine(535, " Error: authentication failed");
 }
 protected static void AuthPlain(SmtpServerSession context, SmtpClientInputLine input)
 {
     try
     {
         context._CurrentHandlers = _AuthPlainHandlers;
         if (input.Command.ToUpper() == "AUTH")
         {
             context.ClearIdentity();
             var user = input.Params.Skip(1).FirstOrDefault() ?? "";
             if (user.IsNullOrEmpty())
             {
                 context.WriteLine(334, "Username:"******"Password:"******"Password:".GetBytes().ToBase64());
         }
         else
         {
             var password = input.RawInput.Base64ToBytes().ToString(Encoding.UTF8);
             var found = context.Server.Credentials.Any(c => c.UserName == context.User.Name && c.Password == password);
             if (found == false)
             {
                 FailAuthentication(context);
             }
             else
             {
                 Authentication(context);
             }
         }
     }
     catch (FormatException)
     {
         context._CurrentHandlers = _InitialHandlers;
         UnknownCommand(context, input);
     }
 }
 protected static void Authentication(SmtpServerSession context)
 {
     context._User.IsAuthenticated = true;
     context._CurrentHandlers = _InitialHandlers;
     context.WriteLine(235, "Authentication successful");
 }
 protected static void OnMailFrom(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.Params.Length != 2 || input.Params.First().ToUpper() != "FROM:") UnknownCommand(context, input);
     else
     {
         context.Message.MailFrom = input.Params.Last();
     }
     context.WriteLine(250, "Ok");
 }
 protected static void OnData(SmtpServerSession context, SmtpClientInputLine input)
 {
     context._CurrentHandlers = _HeaderHandlers;
     context.WriteLine(354, "Ok");
 }
 protected static void HandleOK(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(250, "Ok");
 }
 protected static void UnknownCommand(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(502, "Error: command not implemented");
 }
 protected static void OnQuit(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(221, "Bye");
     context.EndSession();
 }
 protected static void FailAuthentication(SmtpServerSession context)
 {
     context.ClearIdentity();
     context._CurrentHandlers = _InitialHandlers;
     context.WriteLine(535, " Error: authentication failed");
 }
 protected static void Authentication(SmtpServerSession context)
 {
     context._User.IsAuthenticated = true;
     context._CurrentHandlers      = _InitialHandlers;
     context.WriteLine(235, "Authentication successful");
 }
 protected static void HandleBody(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.RawInput == ".")
     {
         context.FireReceieMessage();
         context._CurrentHandlers = _InitialHandlers;
         context.Reset();
         context.WriteLine(250, "Ok");
     }
     else context.Message.Data.Add(input.RawInput);
 }
 protected static void HandleHeader(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.RawInput == "") context._CurrentHandlers = _BodyHandlers;
     else context.Message.Headers.Add(input.RawInput);
 }
 protected static void OnData(SmtpServerSession context, SmtpClientInputLine input)
 {
     context._CurrentHandlers = _HeaderHandlers;
     context.WriteLine(354, "Ok");
 }
 protected static void OnAuth(SmtpServerSession context, SmtpClientInputLine input)
 {
     var loginMethod = input.Params.First();
     switch (loginMethod.ToUpper())
     {
         case "LOGIN":
             AuthPlain(context, input);
             return;
         case "CRAM-MD5":
             AuthCRAMMD5(context, input);
             return;
         default:
             FailAuthentication(context);
             break;
     }
 }
 protected static void OnRcptTo(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (input.Params.Length != 2 || input.Params.First().ToUpper() != "TO:")
     {
         UnknownCommand(context, input);
         return;
     }
     var rcptto = input.Params.Last();
     if (context.Server.Credentials.Any() && context.User.IsAuthenticated == false)
     {
         context.WriteLine(554, "{0}: Recipient address rejected: Access denied", rcptto);
         return;
     }
     context.Message.RcptTo.Add(rcptto);
     context.WriteLine(250, "Ok");
 }
 protected static void OnEHLO(SmtpServerSession context, SmtpClientInputLine input)
 {
     if (context.Server.Credentials.Any())
     {
         context.WriteLine(
             "250-localhost\r\n" +
             "250-AUTH CRAM-MD5\r\n" +
             "250-AUTH LOGIN CRAM-MD5\r\n" +
             "250-AUTH=CRAM-MD5\r\n" +
             "250 AUTH=LOGIN CRAM-MD5");
     }
     else context.WriteLine(250, "Ok");
 }
 public SmtpServerSessionThread(SmtpServerSession session, Thread thread)
 {
     this.Session = session;
     this.Thread  = thread;
 }
 protected static void OnQuit(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(221, "Bye");
     context.EndSession();
 }
 protected static void HandleOK(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(250, "Ok");
 }
 protected static void UnknownCommand(SmtpServerSession context, SmtpClientInputLine input)
 {
     context.WriteLine(502, "Error: command not implemented");
 }
        protected static void AuthCRAMMD5(SmtpServerSession context, SmtpClientInputLine input)
        {
            try
            {
                const string AuthCRAMMD5Key = "AuthCRAMMD5Key";
                context._CurrentHandlers = _AuthCRAMMD5Handlers;
                if (input.Command.ToUpper() == "AUTH")
                {
                    context.ClearIdentity();
                    context.Items[AuthCRAMMD5Key] = Guid.NewGuid().ToByteArray().ToBase64();
                    context.WriteLine(334, context.Items[AuthCRAMMD5Key] as string);
                }
                else
                {
                    var pair = input.RawInput.Base64ToBytes().ToString(Encoding.UTF8).Split(' ');
                    context._User.Name = pair.First();
                    var credential = context.Server
                        .Credentials
                        .FirstOrDefault(c => c.UserName == context._User.Name);
                    if (credential == null)
                    {
                        FailAuthentication(context);
                        return;
                    }

                    var hmacmd5str = new HMACMD5(credential.Password.GetBytes())
                        .ComputeHash(context.Items[AuthCRAMMD5Key].ToString().Base64ToBytes())
                        .ToHexString();
                    context.Items.Remove(AuthCRAMMD5Key);
                    if (hmacmd5str != pair.Last())
                    {
                        FailAuthentication(context);
                    }
                    else
                    {
                        Authentication(context);
                    }
                }
            }
            catch (FormatException)
            {
                context._CurrentHandlers = _InitialHandlers;
                UnknownCommand(context, input);
            }
        }
        private void OnAcceptTcpClient(IAsyncResult ar)
        {
            var listener = ar.AsyncState as TcpListener;
            try
            {
                var tcpClient = listener.EndAcceptTcpClient(ar);
                lock (this)
                {
                    CleanUpSessionTreadsList();
                    var session = new SmtpServerSession(this, tcpClient);
                    var sessionThread = new SmtpServerSessionThread(session,
                        new Thread(() =>
                    {
                        session.ExecuteSession();
                    }));
                    _SessionThreads.Add(sessionThread);
                    sessionThread.Thread.Start();
                }
            }
            catch (ObjectDisposedException)
            {
                return;
            }

            listener.BeginAcceptTcpClient(OnAcceptTcpClient, listener);
        }
 public SmtpServerSessionThread(SmtpServerSession session, Thread thread)
 {
     this.Session = session;
     this.Thread = thread;
 }