public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { await context.Stream.ReplyAsync(SmtpResponse.ServiceReady, cancellationToken); SslStream sslStream = new SslStream(context.Stream.GetInnerStream(), true); await sslStream.AuthenticateAsServerAsync(_certificate, false, SslProtocols.Default, true); context.Stream = new NetworkTextStream(sslStream); }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { if (context.To.Count == 0) { await context.Stream.ReplyAsync(SmtpResponse.NoValidRecipientsGiven, cancellationToken).ConfigureAwait(false); } else { await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.StartMailInput, "end with <CRLF>.<CRLF>"), cancellationToken).ConfigureAwait(false); string text; while ((text = await context.Stream.ReadLineAsync(cancellationToken).ConfigureAwait(false)) != ".") { context.AppendLine(text.TrimStart(new char[] { '.' })); } try { string arg = OnMessage(context); await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.Ok, string.Format("mail accepted ({0})", arg)), cancellationToken).ConfigureAwait(false); } catch (Exception) { await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.MailboxUnavailable, null), cancellationToken).ConfigureAwait(false); } } }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { switch (_method) { case AuthenticationMethod.Login: if (!(await TryLogin(context, cancellationToken))) { await context.Stream.ReplyAsync(SmtpResponse.AuthenticationFailed, cancellationToken).ConfigureAwait(false); return; } break; case AuthenticationMethod.Plain: if (!(await TryPlain(context, cancellationToken))) { await context.Stream.ReplyAsync(SmtpResponse.AuthenticationFailed, cancellationToken).ConfigureAwait(false); return; } break; } if (!_userAuthenticator(context, _user, _password)) { await context.Stream.ReplyAsync(SmtpResponse.AuthenticationFailed, cancellationToken).ConfigureAwait(false); } else { await context.Stream.ReplyAsync(SmtpResponse.AuthenticationSuccessful, cancellationToken).ConfigureAwait(false); } }
private async Task ListenAsync(IPEndPoint endpoint, CancellationToken cancellationToken) { var tcpListener = new TcpListener(endpoint); tcpListener.Start(); var sessions = new ConcurrentDictionary <Task, Task>(); try { while (!cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); var tcpClient = await tcpListener.AcceptTcpClientAsync().WithCancellation(cancellationToken).ConfigureAwait(false); var smtpSession = new SmtpSession(this, tcpClient); var task = smtpSession.HandleAsync(cancellationToken).ContinueWith(delegate(Task t) { Task task2; sessions.TryRemove(t, out task2); tcpClient.Close(); }); sessions.TryAdd(task, task); } await Task.WhenAll(sessions.Values).ConfigureAwait(false); } finally { tcpListener.Stop(); } }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { context.Reset(); int messageSize = GetMessageSize(); if (_maxMessageSize > 0 && messageSize > _maxMessageSize) { await context.Stream.ReplyAsync(SmtpResponse.SizeLimitExceeded, cancellationToken); return; } switch (_filter(Address)) { case ValidationResult.Yes: context.From = Address; await context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken); break; case ValidationResult.NoTemporarily: await context.Stream.ReplyAsync(SmtpResponse.MailboxUnavailable, cancellationToken); break; case ValidationResult.NoPermanently: await context.Stream.ReplyAsync(SmtpResponse.MailboxNameNotAllowed, cancellationToken); break; default: throw new NotSupportedException("The Acceptance state is not supported."); } }
private async Task <bool> TryLogin(SmtpSession context, CancellationToken cancellationToken) { await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.ContinueWithAuth, "VXNlcm5hbWU6"), cancellationToken); _user = Encoding.UTF8.GetString(Convert.FromBase64String(await context.Stream.ReadLineAsync(cancellationToken).ConfigureAwait(false))); await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.ContinueWithAuth, "UGFzc3dvcmQ6"), cancellationToken); _password = Encoding.UTF8.GetString(Convert.FromBase64String(await context.Stream.ReadLineAsync(cancellationToken).ConfigureAwait(false))); return(true); }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { string[] array = new string[] { DomainOrAddress }.Union(GetExtensions(context as SmtpSession)).ToArray <string>(); for (int i = 0; i < array.Length - 1; i++) { await context.Stream.WriteLineAsync(string.Format("250-{0}", array[i]), cancellationToken); } await context.Stream.WriteLineAsync(string.Format("250 {0}", array[array.Length - 1]), cancellationToken); await context.Stream.FlushAsync(cancellationToken); }
private IEnumerable <string> GetExtensions(SmtpSession session) { yield return("PIPELINING"); if (!session.Stream.IsSecure && _server.ServerCertificate != null) { yield return("STARTTLS"); } if (_server.MaxMessageSize > 0) { yield return(string.Format("SIZE {0}", _server.MaxMessageSize)); } if (session.Stream.IsSecure && _server.UserAuthenticator != null) { yield return("AUTH PLAIN LOGIN"); } yield break; }
private async Task <bool> TryPlain(SmtpSession context, CancellationToken cancellationToken) { await context.Stream.ReplyAsync(new SmtpResponse(SmtpReplyCode.ContinueWithAuth, " "), cancellationToken).ConfigureAwait(false); string @string = Encoding.UTF8.GetString(Convert.FromBase64String(await context.Stream.ReadLineAsync(cancellationToken).ConfigureAwait(false))); Match match = Regex.Match(@string, "\0(?<user>.*)\0(?<password>.*)"); bool result; if (!match.Success) { await context.Stream.ReplyAsync(SmtpResponse.AuthenticationFailed, cancellationToken).ConfigureAwait(false); result = false; } else { _user = match.Groups["user"].Value; _password = match.Groups["password"].Value; result = true; } return(result); }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { switch (_filter(context, Address)) { case ValidationResult.Yes: context.To.Add(Address); await context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken); break; case ValidationResult.NoTemporarily: await context.Stream.ReplyAsync(SmtpResponse.MailboxUnavailable, cancellationToken); break; case ValidationResult.NoPermanently: await context.Stream.ReplyAsync(SmtpResponse.MailboxNameNotAllowed, cancellationToken); break; default: throw new NotSupportedException("The Acceptance state is not supported."); } }
public abstract Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken);
public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { SmtpResponse response = new SmtpResponse(_response.ReplyCode, string.Format("{0}, {1} retry(ies) remaining.", _response.Message, context.RetryCount)); return(context.Stream.ReplyAsync(response, cancellationToken)); }
public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { return(context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken)); }
public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { await context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken).ConfigureAwait(false); }
public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { SmtpResponse response = new SmtpResponse(SmtpReplyCode.Ok, string.Format("Hello {0}, haven't we met before?", Domain)); return(context.Stream.ReplyAsync(response, cancellationToken)); }
public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken) { context.Close(); return(context.Stream.ReplyAsync(SmtpResponse.ServiceClosingTransmissionChannel, cancellationToken)); }