SmtpServer is a simple, but highly functional SMTP server implementation. Written entirely in C# it takes full advantage of the .NET TPL to achieve maximum performance.
SmtpServer is available via NuGet
Check the Changelog
SmtpServer currently supports the following ESMTP extensions:
At its most basic, it only takes a few lines of code for the server to be listening to incoming requests.
var options = new SmtpServerOptionsBuilder() .ServerName("localhost") .Port(25, 587) .Build(); var smtpServer = new SmtpServer.SmtpServer(options, ServiceProvider.Default); await smtpServer.StartAsync(CancellationToken.None);
There are three hooks that can be implemented; IMessageStore, IMailboxFilter, and IUserAuthenticator.
var options = new SmtpServerOptionsBuilder() .ServerName("localhost") .Endpoint(builder => builder .Port(9025, true) .AllowUnsecureAuthentication(false) .Certificate(CreateCertificate())) .Build(); var serviceProvider = new ServiceProvider(); serviceProvider.Add(new SampleMessageStore()); serviceProvider.Add(new SampleMailboxFilter()); serviceProvider.Add(new SampleUserAuthenticator()); var smtpServer = new SmtpServer.SmtpServer(options, serviceProvider); await smtpServer.StartAsync(CancellationToken.None); // to create an X509Certificate for testing you need to run MAKECERT.EXE and then PVK2PFX.EXE // http://www.digitallycreated.net/Blog/38/using-makecert-to-create-certificates-for-development static X509Certificate2 CreateCertificate() { var certificate = File.ReadAllBytes(@"Certificate.pfx"); return new X509Certificate2(certificate, "P@ssw0rd"); }
public class SampleMessageStore : MessageStore { public override async Task<SmtpResponse> SaveAsync(ISessionContext context, IMessageTransaction transaction, ReadOnlySequence<byte> buffer, CancellationToken cancellationToken) { await using var stream = new MemoryStream(); var position = buffer.GetPosition(0); while (buffer.TryGet(ref position, out var memory)) { await stream.WriteAsync(memory, cancellationToken); } stream.Position = 0; var message = await MimeKit.MimeMessage.LoadAsync(stream, cancellationToken); Console.WriteLine(message.TextBody); return SmtpResponse.Ok; } }
public class SampleMailboxFilter : IMailboxFilter, IMailboxFilterFactory { public Task<MailboxFilterResult> CanAcceptFromAsync(ISessionContext context, IMailbox @from, int size, CancellationToken cancellationToken) { if (String.Equals(@from.Host, "test.com")) { return Task.FromResult(MailboxFilterResult.Yes); } return Task.FromResult(MailboxFilterResult.NoPermanently); } public Task<MailboxFilterResult> CanDeliverToAsync(ISessionContext context, IMailbox to, IMailbox @from, CancellationToken token) { return Task.FromResult(MailboxFilterResult.Yes); } public IMailboxFilter CreateInstance(ISessionContext context) { return new SampleMailboxFilter(); } }
public class SampleUserAuthenticator : IUserAuthenticator, IUserAuthenticatorFactory { public Task<bool> AuthenticateAsync(ISessionContext context, string user, string password, CancellationToken token) { Console.WriteLine("User={0} Password={1}", user, password); return Task.FromResult(user.Length > 4); } public IUserAuthenticator CreateInstance(ISessionContext context) { return new SampleUserAuthenticator(); } }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4