{"id":22517585,"url":"https://github.com/zabszk/csharp-smtp-server","last_synced_at":"2025-08-22T03:32:31.487Z","repository":{"id":104371448,"uuid":"180838665","full_name":"zabszk/CSharp-SMTP-Server","owner":"zabszk","description":"SMTP Server in C#","archived":false,"fork":false,"pushed_at":"2024-09-19T16:22:13.000Z","size":217,"stargazers_count":19,"open_issues_count":5,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-11T03:23:34.428Z","etag":null,"topics":["csharp","csharp-library","netstandard","network","networking","server","smtp","smtp-library","smtp-listerner","smtp-protocol","smtp-server"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zabszk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-11T16:57:28.000Z","updated_at":"2025-06-24T20:51:26.000Z","dependencies_parsed_at":"2023-12-25T20:32:04.643Z","dependency_job_id":"48482f3f-c66d-4de2-9324-97990f4dcb2a","html_url":"https://github.com/zabszk/CSharp-SMTP-Server","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/zabszk/CSharp-SMTP-Server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zabszk%2FCSharp-SMTP-Server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zabszk%2FCSharp-SMTP-Server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zabszk%2FCSharp-SMTP-Server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zabszk%2FCSharp-SMTP-Server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zabszk","download_url":"https://codeload.github.com/zabszk/CSharp-SMTP-Server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zabszk%2FCSharp-SMTP-Server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271579436,"owners_count":24784250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","csharp-library","netstandard","network","networking","server","smtp","smtp-library","smtp-listerner","smtp-protocol","smtp-server"],"created_at":"2024-12-07T04:09:57.392Z","updated_at":"2025-08-22T03:32:31.164Z","avatar_url":"https://github.com/zabszk.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CSharp-SMTP-Server [![GitHub release](https://flat.badgen.net/github/release/zabszk/CSharp-SMTP-Server)](https://github.com/zabszk/CSharp-SMTP-Server/releases/) [![NuGet](https://flat.badgen.net/nuget/v/CSharp-SMTP-Server/latest)](https://www.nuget.org/packages/CSharp-SMTP-Server/) [![License](https://flat.badgen.net/github/license/zabszk/CSharp-SMTP-Server)](https://github.com/zabszk/CSharp-SMTP-Server/blob/master/LICENSE)\nSimple (receive only) SMTP server library for C#.\n\nThis server is only returning all received emails to interface provided by the software running this library.\n\n# Supported features\n* TLS and STARTTLS\n* AUTH LOGIN and AUTH PLAIN\n\n# Compatible with\n* RFC 822 (STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES)\n* RFC 1869 (SMTP Service Extensions)\n* RFC 2554 (SMTP Service Extension for Authentication)\n* RFC 3463 (Enhanced Mail System Status Codes)\n* RFC 4616 (The PLAIN Simple Authentication and Security Layer (SASL) Mechanism)\n* RFC 4954 (SMTP Service Extension for Authentication)\n* RFC 5321 (SMTP Protocol)\n* RFC 7208 (Sender Policy Framework)\n* RFC 7372 (Email Authentication Status Codes)\n* RFC 7489 (Domain-based Message Authentication, Reporting, and Conformance (DMARC)) [Partially Supported]\n\n# 3rd party services and libraries usage\n* This library by default uses Cloudflare Public DNS Servers (1.1.1.1) to perform SPF and DMARC validation. IP address of the DNS server can be changed or both validations can be disabled using ServerOptions class.\n* This library by default downloads Public Suffix List managed by Mozilla Foundation from GitHub. The list is licensed under Mozilla Public License v. 2.0. The download URL can be changed in ServerOptions class. The list is NOT downloaded if DnsServerEndpoint is set to null in ServerOptions class.\n* This library uses [MimeKit](https://github.com/jstedfast/MimeKit) library created by .NET Foundation and Contributors and licensed under [The MIT License](https://raw.githubusercontent.com/jstedfast/MimeKit/master/LICENSE).\n\n# Basic usage\n```cs\nvar server = new SMTPServer(new[]\n{\n\tnew ListeningParameters(IPAddress.IPv6Any, new ushort[]{25, 587}, new ushort[]{465}, true)\n}, new ServerOptions(){ServerName = \"Test SMTP Server\", RequireEncryptionForAuth = false}, new DeliveryInterface(), new LoggerInterface());\n//with TLS:\n//}, new ServerOptions() { ServerName = \"Test SMTP Server\", RequireEncryptionForAuth = true}, new DeliveryInterface(), new LoggerInterface(), new X509Certificate2(\"PathToCertWithKey.pfx\"));\n\t\t\nserver.SetAuthLogin(new AuthenticationInterface());\nserver.SetFilter(new FilterInterface());\nserver.Start();\n```\n      \n```cs\nclass LoggerInterface : ILogger\n{\n\tpublic void LogError(string text) =\u003e Console.WriteLine(\"[LOG] \" + text);\n}\n```\n  \n```cs\nclass DeliveryInterface : IMailDelivery\n{\n\t//Let's just print all emails\n\tpublic Task EmailReceived(MailTransaction transaction)\n\t{\n\t\tConsole.WriteLine(\n\t\t\t$\"\\n\\n--- EMAIL TRANSACTION ---\\nSource IP: {transaction.RemoteEndPoint}\\nAuthenticated: {transaction.AuthenticatedUser ?? \"(not authenticated)\"}\\nFrom: {transaction.From}\\nTo (Commands): {transaction.DeliverTo.Aggregate((current, item) =\u003e current + \", \" + item)}\\nTo (Headers): {transaction.To.Aggregate((current, item) =\u003e current + \", \" + item)}\\nCc: {transaction.Cc.Aggregate((current, item) =\u003e current + \", \" + item)}\\nBcc: {transaction.Bcc.Aggregate((current, item) =\u003e current + \", \" + item)}\\nBody: {transaction.Body}\\n--- END OF TRANSACTION ---\\n\\n\");\n\t\treturn Task.CompletedTask;\n\t}\n\n\t//We only own \"@smtp.demo\" and we don't want any emails to other domains\n\tpublic Task\u003cUserExistsCodes\u003e DoesUserExist(string emailAddress) =\u003e Task.FromResult(emailAddress.EndsWith(\"@smtp.demo\", StringComparison.OrdinalIgnoreCase)\n\t\t? UserExistsCodes.DestinationAddressValid\n\t\t: UserExistsCodes.BadDestinationSystemAddress);\n}\n```\n\n```cs\nclass AuthenticationInterface : IAuthLogin\n{\n\t//123 is password for all users (NOT SECURE, ONLY FOR DEMO PURPOSES!)\n\n\tpublic Task\u003cbool\u003e CheckAuthCredentials(string authorizationIdentity, string authenticationIdentity, string password,\n\t\tEndPoint remoteEndPoint,\n\t\tbool secureConnection) =\u003e Task.FromResult(password == \"123\");\n}\n```\n\n```cs\nclass FilterInterface : IMailFilter\n{\n\t//Allow all connections\n\tpublic Task\u003cSmtpResult\u003e IsConnectionAllowed(EndPoint ep) =\u003e Task.FromResult(new SmtpResult(SmtpResultType.Success));\n\n\t//Let's block .invalid TLD\n\tpublic Task\u003cSmtpResult\u003e IsAllowedSender(string source, EndPoint ep) =\u003e Task.FromResult(source.TrimEnd().EndsWith(\".invalid\")\n\t\t? new SmtpResult(SmtpResultType.PermanentFail)\n\t\t: new SmtpResult(SmtpResultType.Success));\n\t\t\n\t//Let's reject Softfail as well\n\tpublic Task\u003cSmtpResult\u003e IsAllowedSenderSpfVerified(string source, EndPoint? ep, SpfResult spfResult) =\u003e Task.FromResult(spfResult == SpfResult.Softfail\n\t\t? new SmtpResult(SmtpResultType.PermanentFail)\n\t\t: new\n\t\t\tSmtpResult(SmtpResultType.Success));\n\n\t//Let's block all emails to root at any domain\n\tpublic Task\u003cSmtpResult\u003e CanDeliver(string source, string destination, bool authenticated, string username,\n\t\tEndPoint ep) =\u003e Task.FromResult(destination.TrimStart().StartsWith(\"root@\", StringComparison.OrdinalIgnoreCase)\n\t\t? new SmtpResult(SmtpResultType.PermanentFail)\n\t\t: new SmtpResult(SmtpResultType.Success));\n\n\t//Let's blacklist word \"spam\"\n\tpublic Task\u003cSmtpResult\u003e CanProcessTransaction(MailTransaction transaction) =\u003e Task.FromResult(transaction.GetMessageBody() != null \u0026\u0026 transaction.GetMessageBody()!.Contains(\"spam\", StringComparison.OrdinalIgnoreCase)\n\t\t? new SmtpResult(SmtpResultType.PermanentFail)\n\t\t: new SmtpResult(SmtpResultType.Success));\n}\n```\n\n# Generating PFX from PEM keys\nYou can generate PFX from PEM certificate and PEM private key using openssl:\n```\nopenssl pkcs12 -export -in public.pem -inkey private.pem -out CertWithKey.pfx\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzabszk%2Fcsharp-smtp-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzabszk%2Fcsharp-smtp-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzabszk%2Fcsharp-smtp-server/lists"}