CSharp-SMTP-Server
1.1.1
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package CSharp-SMTP-Server --version 1.1.1
NuGet\Install-Package CSharp-SMTP-Server -Version 1.1.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CSharp-SMTP-Server" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CSharp-SMTP-Server --version 1.1.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: CSharp-SMTP-Server, 1.1.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CSharp-SMTP-Server as a Cake Addin #addin nuget:?package=CSharp-SMTP-Server&version=1.1.1 // Install CSharp-SMTP-Server as a Cake Tool #tool nuget:?package=CSharp-SMTP-Server&version=1.1.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
CSharp-SMTP-Server
Simple (receive only) SMTP server library for C#.
This server is only returning all received emails to interface provided by the software running this library.
Supported features
- TLS and STARTTLS
- AUTH LOGIN and AUTH PLAIN
Compatible with
- RFC 822 (STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES)
- RFC 1869 (SMTP Service Extensions)
- RFC 2554 (SMTP Service Extension for Authentication)
- RFC 3463 (Enhanced Mail System Status Codes)
- RFC 4616 (The PLAIN Simple Authentication and Security Layer (SASL) Mechanism)
- RFC 4954 (SMTP Service Extension for Authentication)
- RFC 5321 (SMTP Protocol)
- RFC 7208 (Sender Policy Framework)
Basic usage
var server = new SMTPServer(new[]
{
new ListeningParameters(IPAddress.Any, new ushort[]{25, 587}, new ushort[]{465}),
new ListeningParameters(IPAddress.IPv6Any, new ushort[]{25, 587}, new ushort[]{465})
}, new ServerOptions(){ServerName = "Test SMTP Server", RequireEncryptionForAuth = false}, new DeliveryInterface(), new LoggerInterface());
//with TLS:
//}, new ServerOptions() { ServerName = "Test SMTP Server", RequireEncryptionForAuth = true}, new DeliveryInterface(), new LoggerInterface(), new X509Certificate2("PathToCertWithKey.pfx"));
server.SetAuthLogin(new AuthenticationInterface());
server.SetFilter(new FilterInterface());
server.Start();
class LoggerInterface : ILogger
{
public void LogError(string text) => Console.WriteLine("[LOG] " + text);
}
class DeliveryInterface : IMailDelivery
{
//Let's just print all emails
public Task EmailReceived(MailTransaction transaction)
{
Console.WriteLine(
$"\n\n--- EMAIL TRANSACTION ---\nSource IP: {transaction.RemoteEndPoint}\nAuthenticated: {transaction.AuthenticatedUser ?? "(not authenticated)"}\nFrom: {transaction.From}\nTo (Commands): {transaction.DeliverTo.Aggregate((current, item) => current + ", " + item)}\nTo (Headers): {transaction.To.Aggregate((current, item) => current + ", " + item)}\nCc: {transaction.Cc.Aggregate((current, item) => current + ", " + item)}\nBcc: {transaction.Bcc.Aggregate((current, item) => current + ", " + item)}\nBody: {transaction.Body}\n--- END OF TRANSACTION ---\n\n");
return Task.CompletedTask;
}
//We only own "@smtp.demo" and we don't want any emails to other domains
public Task<UserExistsCodes> DoesUserExist(string emailAddress) => Task.FromResult(emailAddress.EndsWith("@smtp.demo", StringComparison.OrdinalIgnoreCase)
? UserExistsCodes.DestinationAddressValid
: UserExistsCodes.BadDestinationSystemAddress);
}
class AuthenticationInterface : IAuthLogin
{
//123 is password for all users (NOT SECURE, ONLY FOR DEMO PURPOSES!)
public Task<bool> AuthPlain(string authorizationIdentity, string authenticationIdentity, string password,
EndPoint remoteEndPoint,
bool secureConnection) => Task.FromResult(password == "123");
public Task<bool> AuthLogin(string login, string password, EndPoint remoteEndPoint, bool secureConnection) =>
Task.FromResult(password == "123");
}
class FilterInterface : IMailFilter
{
//Allow all connections
public Task<SmtpResult> IsConnectionAllowed(EndPoint ep) => Task.FromResult(new SmtpResult(SmtpResultType.Success));
//Let's block .invalid TLD. You can do here eg. SPF validation
public Task<SmtpResult> IsAllowedSender(string source, EndPoint ep) => Task.FromResult(source.TrimEnd().EndsWith(".invalid")
? new SmtpResult(SmtpResultType.PermanentFail)
: new SmtpResult(SmtpResultType.Success));
//Let's reject Softfail as well
public Task<SmtpResult> IsAllowedSenderSpfVerified(string source, EndPoint? ep, SpfResult spfResult) => Task.FromResult(spfResult == SpfResult.Softfail
? new SmtpResult(SmtpResultType.PermanentFail)
: new
SmtpResult(SmtpResultType.Success));
//Let's block all emails to root at any domain
public Task<SmtpResult> CanDeliver(string source, string destination, bool authenticated, string username,
EndPoint ep) => Task.FromResult(destination.TrimStart().StartsWith("root@", StringComparison.OrdinalIgnoreCase)
? new SmtpResult(SmtpResultType.PermanentFail)
: new SmtpResult(SmtpResultType.Success));
//Let's blacklist word "spam"
public Task<SmtpResult> CanProcessTransaction(MailTransaction transaction) => Task.FromResult(transaction.Body != null && transaction.Body.ToLower().Contains("spam", StringComparison.OrdinalIgnoreCase)
? new SmtpResult(SmtpResultType.PermanentFail)
: new SmtpResult(SmtpResultType.Success));
}
Generating PFX from PEM keys
You can generate PFX from PEM certificate and PEM private key using openssl:
openssl pkcs12 -export -in public.pem -inkey private.pem -out CertWithKey.pfx
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.1
- zabszk.DnsClient (>= 1.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.