/// <summary> /// Called when the session has been authenticated. /// </summary> /// <param name="sender">The object that raised the event.</param> /// <param name="eventArgs">The event data.</param> void OnSessionAuthenticated(object sender, EventArgs eventArgs) { _context.SessionAuthenticated -= OnSessionAuthenticated; WaitingForMail.Remove(AuthCommand.Command); WaitingForMailSecure.Remove(AuthCommand.Command); if (_context.EndpointDefinition.AuthenticationRequired) { WaitingForMail.Replace(MailCommand.Command, TryMakeMail, SmtpState.WithinTransaction); WaitingForMailSecure.Replace(MailCommand.Command, TryMakeMail, SmtpState.WithinTransaction); } }
/// <summary> /// Constructor. /// </summary> /// <param name="context">The SMTP server session context.</param> internal SmtpStateMachine(SmtpSessionContext context) { _context = context; _context.SessionAuthenticated += OnSessionAuthenticated; _stateTable = new StateTable { new State(SmtpState.Initialized) { { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset }, { QuitCommand.Command, TryMakeQuit }, { HeloCommand.Command, TryMakeHelo, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, { EhloCommand.Command, TryMakeEhlo, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, }, new State(SmtpState.WaitingForMail) { { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset }, { QuitCommand.Command, TryMakeQuit }, { HeloCommand.Command, TryMakeHelo, SmtpState.WaitingForMail }, { EhloCommand.Command, TryMakeEhlo, SmtpState.WaitingForMail }, { MailCommand.Command, TryMakeMail, SmtpState.WithinTransaction } }, new State(SmtpState.WaitingForMailSecure) { { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset }, { QuitCommand.Command, TryMakeQuit }, { AuthCommand.Command, TryMakeAuth }, { HeloCommand.Command, TryMakeHelo, SmtpState.WaitingForMailSecure }, { EhloCommand.Command, TryMakeEhlo, SmtpState.WaitingForMailSecure }, { MailCommand.Command, TryMakeMail, SmtpState.WithinTransaction } }, new State(SmtpState.WithinTransaction) { { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, { QuitCommand.Command, TryMakeQuit }, { RcptCommand.Command, TryMakeRcpt, SmtpState.CanAcceptData }, }, new State(SmtpState.CanAcceptData) { { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, { QuitCommand.Command, TryMakeQuit }, { RcptCommand.Command, TryMakeRcpt }, { DataCommand.Command, TryMakeData, SmtpState.WaitingForMail }, } }; if (context.EndpointDefinition.AllowUnsecureAuthentication) { WaitingForMail.Add(AuthCommand.Command, TryMakeAuth); } if (context.EndpointDefinition.AuthenticationRequired) { WaitingForMail.Replace(MailCommand.Command, MakeResponse(SmtpResponse.AuthenticationRequired)); WaitingForMailSecure.Replace(MailCommand.Command, MakeResponse(SmtpResponse.AuthenticationRequired)); } if (context.ServerOptions.ServerCertificate != null && context.NetworkClient.Stream.IsSecure == false) { WaitingForMail.Add(StartTlsCommand.Command, TryMakeStartTls, SmtpState.WaitingForMailSecure); } _stateTable.Initialize(SmtpState.Initialized); }