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);
		}
Exemple #2
0
        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);
                }
            }
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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();
            }
        }
Exemple #5
0
        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.");
            }
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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;
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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.");
            }
        }
Exemple #11
0
 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));
        }
Exemple #13
0
 public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken)
 {
     return(context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken));
 }
Exemple #14
0
 public override async Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken)
 {
     await context.Stream.ReplyAsync(SmtpResponse.Ok, cancellationToken).ConfigureAwait(false);
 }
Exemple #15
0
        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));
        }
Exemple #16
0
 public override Task ExecuteAsync(SmtpSession context, CancellationToken cancellationToken)
 {
     context.Close();
     return(context.Stream.ReplyAsync(SmtpResponse.ServiceClosingTransmissionChannel, cancellationToken));
 }