Skip to content

Commit f744184

Browse files
committed
Merge branch 'release/7.6.0'
2 parents 7cd541a + af3ce3e commit f744184

File tree

113 files changed

+3554
-1502
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+3554
-1502
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ on:
2121
default: true
2222

2323
env:
24-
DOTNET_VERSION: '8.0.x'
24+
DOTNET_VERSION: '9.0.x'
2525
CONFIGURATION: Release
2626

2727
jobs:

DOCKERHUB.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,20 @@ docker run -d \
8484
- `SmtpServer__Port` - SMTP listening port (default: 2525, use 587 for STARTTLS)
8585
- `SmtpServer__MessagePath` - Path where emails are stored (default: /app/Incoming)
8686
- `SmtpServer__LoggingPath` - Path for log files (default: /app/logs)
87+
- `SmtpServer__AllowedIps` - IP allowlist for SMTP connections (default: "*" = all IPs allowed)
8788
- `Urls` - HTTP server URLs (default: http://0.0.0.0:8080)
8889

90+
**Security - SMTP IP Allowlist Configuration:**
91+
- `SmtpServer__AllowedIps` - Comma-separated list of allowed IP addresses or CIDR ranges for SMTP connections
92+
- `*` - Allow all IPs (default, backward compatible)
93+
- `192.168.1.0/24` - Allow single CIDR range
94+
- `192.168.1.0/24,10.0.0.0/8` - Allow multiple CIDR ranges
95+
- `192.168.1.100` - Allow single IP
96+
- `192.168.1.100,192.168.1.101` - Allow multiple specific IPs
97+
- Localhost (127.0.0.1/::1) is always allowed
98+
- Supports both IPv4 and IPv6
99+
- Note: This restricts SMTP connections only, not HTTP web UI access
100+
89101
**TLS/STARTTLS Configuration (Optional):**
90102
- `SmtpServer__CertificateFindType` - Certificate search method (default: "FindBySubjectName")
91103
- `SmtpServer__CertificateFindValue` - Certificate identifier (empty = TLS disabled)
@@ -366,6 +378,62 @@ Error: Multiple certificates (3) found matching...
366378
367379
## Advanced Examples
368380
381+
### SMTP IP Allowlist / Access Control
382+
383+
Restrict SMTP connections to specific IP addresses or networks using the `SmtpServer__AllowedIps` environment variable:
384+
385+
**Allow specific network:**
386+
```bash
387+
docker run -d \
388+
--name papercut \
389+
-e SmtpServer__AllowedIps=192.168.1.0/24 \
390+
-p 8080:8080 \
391+
-p 2525:2525 \
392+
changemakerstudiosus/papercut-smtp:latest
393+
```
394+
395+
**Allow multiple networks:**
396+
```bash
397+
docker run -d \
398+
--name papercut \
399+
-e SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8,172.16.0.0/12 \
400+
-p 8080:8080 \
401+
-p 2525:2525 \
402+
changemakerstudiosus/papercut-smtp:latest
403+
```
404+
405+
**Allow specific IPs only:**
406+
```bash
407+
docker run -d \
408+
--name papercut \
409+
-e SmtpServer__AllowedIps=192.168.1.100,192.168.1.101 \
410+
-p 8080:8080 \
411+
-p 2525:2525 \
412+
changemakerstudiosus/papercut-smtp:latest
413+
```
414+
415+
**Docker Compose with IP filtering:**
416+
```yaml
417+
services:
418+
papercut:
419+
image: changemakerstudiosus/papercut-smtp:latest
420+
ports:
421+
- "8080:8080"
422+
- "2525:2525"
423+
environment:
424+
- SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8
425+
restart: unless-stopped
426+
```
427+
428+
**Notes:**
429+
- The IP allowlist applies only to SMTP connections, not HTTP web UI access
430+
- Localhost (127.0.0.1 and ::1) is always allowed for SMTP
431+
- Supports CIDR notation for efficient network range specification
432+
- Supports both IPv4 and IPv6 addresses
433+
- Use `SmtpServer__AllowedIps=*` to allow all IPs (default behavior)
434+
- Changes require container restart
435+
- HTTP web UI access is not restricted by this setting
436+
369437
### IPv6 Support
370438

371439
To listen on IPv6:

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<Company>Changemaker Studios</Company>
44
<Description>Standalone SMTP server designed for viewing received messages</Description>
5-
<Copyright>Copyright © 2008 - 2024 Ken Robertson &amp; Jaben Cargman</Copyright>
5+
<Copyright>Copyright © 2008 - 2025 Ken Robertson &amp; Jaben Cargman</Copyright>
66
<Platforms>AnyCPU;x86;x64</Platforms>
77
<DebugType>portable</DebugType>
88
<Nullable>enable</Nullable>

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
1+
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
22
USER $APP_UID
33
WORKDIR /app
44

5-
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
5+
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
66
ARG BUILD_CONFIGURATION=Release
77
ARG BUILD_VERSION=1.0.0.0
88
WORKDIR /work

Papercut.sln

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Build", ".Build", "{8661B3
3131
build-docker.sh = build-docker.sh
3232
build.cake = build.cake
3333
build.ps1 = build.ps1
34+
.github\workflows\build.yml = .github\workflows\build.yml
3435
Directory.Build.props = Directory.Build.props
3536
Dockerfile = Dockerfile
3637
GitVersion.yml = GitVersion.yml
@@ -52,6 +53,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Papercut.Message.Tests", "t
5253
EndProject
5354
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Papercut.Rules.Tests", "test\Papercut.Rules.Tests\Papercut.Rules.Tests.csproj", "{DBD09AAF-2367-CC97-CF28-164BF3E6B721}"
5455
EndProject
56+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Papercut.Infrastructure.Smtp.Tests", "test\Papercut.Infrastructure.Smtp.Tests\Papercut.Infrastructure.Smtp.Tests.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
57+
EndProject
5558
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
5659
ProjectSection(SolutionItems) = preProject
5760
examples\Directory.Build.props = examples\Directory.Build.props
@@ -214,6 +217,18 @@ Global
214217
{DBD09AAF-2367-CC97-CF28-164BF3E6B721}.Release|x64.Build.0 = Release|x64
215218
{DBD09AAF-2367-CC97-CF28-164BF3E6B721}.Release|x86.ActiveCfg = Release|x86
216219
{DBD09AAF-2367-CC97-CF28-164BF3E6B721}.Release|x86.Build.0 = Release|x86
220+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
221+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|AnyCPU.Build.0 = Debug|Any CPU
222+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|x64.ActiveCfg = Debug|x64
223+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|x64.Build.0 = Debug|x64
224+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|x86.ActiveCfg = Debug|x86
225+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|x86.Build.0 = Debug|x86
226+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|AnyCPU.ActiveCfg = Release|Any CPU
227+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|AnyCPU.Build.0 = Release|Any CPU
228+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x64.ActiveCfg = Release|x64
229+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x64.Build.0 = Release|x64
230+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.ActiveCfg = Release|x86
231+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.Build.0 = Release|x86
217232
{F2C325DA-4FC3-4879-4DFB-4CA6AE68A172}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
218233
{F2C325DA-4FC3-4879-4DFB-4CA6AE68A172}.Debug|AnyCPU.Build.0 = Debug|Any CPU
219234
{F2C325DA-4FC3-4879-4DFB-4CA6AE68A172}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -306,6 +321,7 @@ Global
306321
{26A0A4C3-EA5A-490E-9805-5B255DD56994} = {2D6337D4-FD59-49E0-9209-4B06219DB29D}
307322
{9A019B4C-378B-2566-564C-03CD2D1BAFA8} = {2D6337D4-FD59-49E0-9209-4B06219DB29D}
308323
{DBD09AAF-2367-CC97-CF28-164BF3E6B721} = {2D6337D4-FD59-49E0-9209-4B06219DB29D}
324+
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {2D6337D4-FD59-49E0-9209-4B06219DB29D}
309325
{F2C325DA-4FC3-4879-4DFB-4CA6AE68A172} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
310326
{55ACBD38-D261-2659-F089-08C11D90E810} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
311327
{2060C595-6511-88D6-CD97-DF29AD7507F6} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}

ReleaseNotes.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
# Release Notes
22

3+
## Papercut SMTP v7.6.0 [2025-11-08]
4+
5+
### New Features
6+
7+
- **Dark Theme Support** - Added full dark theme support with automatic Windows dark mode detection and synchronization. Fixes [#228](https://github.com/ChangemakerStudios/Papercut-SMTP/issues/228) (Thanks, [wonea](https://github.com/wonea)!)
8+
- System/Light/Dark base theme selection with accent color customization
9+
- Automatic system dark mode detection with live theme updates
10+
- AvalonEdit syntax highlighting supports both light and dark modes
11+
- Theme-aware attachment icons and UI controls throughout the application
12+
- **IP Allowlist Support** - Added IP allowlist filtering for SMTP and HTTP connections with CIDR notation support. Fixes [#333](https://github.com/ChangemakerStudios/Papercut-SMTP/issues/333) (Thanks, [mhkarimi1383](https://github.com/mhkarimi1383)!)
13+
- Configurable via `SmtpServer:AllowedIps` setting
14+
- Support for individual IPs (e.g., `192.168.1.100`) and CIDR ranges (e.g., `192.168.1.0/24`)
15+
- Comprehensive unit tests for IP validation and range matching
16+
- Fail-closed security - blocks all connections if validation fails
17+
- **Dynamic Property Editor for Rules** - Replaced legacy PropertyGrid with custom MahApps.Metro-compatible dynamic property editor
18+
- Reflection-based property discovery using System.ComponentModel attributes
19+
- Intelligent control selection (TextBox, NumericUpDown, ToggleSwitch, PasswordBox)
20+
- Category-based property organization with smart ordering
21+
- Resizable GridSplitter between rules list and property editor
22+
- Full dark theme support in Rules Configuration dialog
23+
24+
### Improvements
25+
26+
- **.NET 9.0 Upgrade** - Upgraded entire solution to .NET 9.0 for improved performance and latest framework features
27+
- **Theme Consistency** - Modernized UI to use dynamic theming with refreshed Options dialog and message list visuals
28+
- **Tab Preservation** - Selected message detail tab (Message/Body/Headers/Raw) now preserved when switching between messages
29+
- **Code Quality** - Fixed numerous compiler warnings and null-safety issues throughout the codebase
30+
- **Resource Management** - Fixed X509Certificate2Collection resource leak
31+
- **Docker Improvements** - Updated container and runtime images for .NET 9.0
32+
33+
### Code Quality
34+
35+
- Comprehensive unit tests for IP allowlist validation
36+
- More flexible SMTP/server startup wiring and options
37+
- Internal robustness improvements with clearer initialization and lifecycle handling
38+
- Better error handling across core components
39+
40+
### Contributors
41+
42+
Special thanks to [wonea](https://github.com/wonea) for requesting dark theme support and [mhkarimi1383](https://github.com/mhkarimi1383) for requesting IP allowlist functionality!
43+
344
## Papercut SMTP v7.5.1 [2025-10-31]
445

546
### Bug Fixes

ReleaseNotesCurrent.md

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
11
# Release Notes
22

3-
## Papercut SMTP v7.5.1 [2025-10-31]
3+
## Papercut SMTP v7.6.0 [2025-11-08]
44

5-
### Bug Fixes
5+
### New Features
66

7-
- **Forwarding Rules Failing** - Fixed critical bug where email forwarding rules were completely broken due to TaskCanceledException. Fixes [#331](https://github.com/ChangemakerStudios/Papercut-SMTP/issues/331) (Thanks, [wcwhitehead](https://github.com/wcwhitehead)!)
8-
- **SSL/TLS Connection Mode** - Fixed SSL/TLS connection mode to use SslOnConnect for port 465 and Auto for STARTTLS
9-
- **SMTP Timeout** - Set proper SMTP timeout of 30 seconds for forwarding rules
10-
- **Backend Service Status** - Fixed initial status detection for backend service
7+
- **Dark Theme Support** - Added full dark theme support with automatic Windows dark mode detection and synchronization. Fixes [#228](https://github.com/ChangemakerStudios/Papercut-SMTP/issues/228) (Thanks, [wonea](https://github.com/wonea)!)
8+
- System/Light/Dark base theme selection with accent color customization
9+
- Automatic system dark mode detection with live theme updates
10+
- AvalonEdit syntax highlighting supports both light and dark modes
11+
- Theme-aware attachment icons and UI controls throughout the application
12+
- **IP Allowlist Support** - Added IP allowlist filtering for SMTP and HTTP connections with CIDR notation support. Fixes [#333](https://github.com/ChangemakerStudios/Papercut-SMTP/issues/333) (Thanks, [mhkarimi1383](https://github.com/mhkarimi1383)!)
13+
- Configurable via `SmtpServer:AllowedIps` setting
14+
- Support for individual IPs (e.g., `192.168.1.100`) and CIDR ranges (e.g., `192.168.1.0/24`)
15+
- Comprehensive unit tests for IP validation and range matching
16+
- Fail-closed security - blocks all connections if validation fails
17+
- **Dynamic Property Editor for Rules** - Replaced legacy PropertyGrid with custom MahApps.Metro-compatible dynamic property editor
18+
- Reflection-based property discovery using System.ComponentModel attributes
19+
- Intelligent control selection (TextBox, NumericUpDown, ToggleSwitch, PasswordBox)
20+
- Category-based property organization with smart ordering
21+
- Resizable GridSplitter between rules list and property editor
22+
- Full dark theme support in Rules Configuration dialog
23+
24+
### Improvements
25+
26+
- **.NET 9.0 Upgrade** - Upgraded entire solution to .NET 9.0 for improved performance and latest framework features
27+
- **Theme Consistency** - Modernized UI to use dynamic theming with refreshed Options dialog and message list visuals
28+
- **Tab Preservation** - Selected message detail tab (Message/Body/Headers/Raw) now preserved when switching between messages
29+
- **Code Quality** - Fixed numerous compiler warnings and null-safety issues throughout the codebase
30+
- **Resource Management** - Fixed X509Certificate2Collection resource leak
31+
- **Docker Improvements** - Updated container and runtime images for .NET 9.0
32+
33+
### Code Quality
34+
35+
- Comprehensive unit tests for IP allowlist validation
36+
- More flexible SMTP/server startup wiring and options
37+
- Internal robustness improvements with clearer initialization and lifecycle handling
38+
- Better error handling across core components
1139

1240
### Contributors
1341

14-
Special thanks to [wcwhitehead](https://github.com/wcwhitehead) for reporting the critical forwarding rules bug!
42+
Special thanks to [wonea](https://github.com/wonea) for requesting dark theme support and [mhkarimi1383](https://github.com/mhkarimi1383) for requesting IP allowlist functionality!

docker-compose.example.yml

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@ services:
1717
- papercut-logs:/app/Logs
1818
environment:
1919
# Basic SMTP configuration
20-
- IP=Any
21-
- Port=2525
20+
- SmtpServer__IP=Any
21+
- SmtpServer__Port=2525
22+
# IP Allowlist for SMTP connections (optional)
23+
# Use "*" to allow all IPs (default), or specify CIDR ranges
24+
# Examples:
25+
# - SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8 # Allow specific networks
26+
# - SmtpServer__AllowedIps=192.168.1.100,192.168.1.101 # Allow specific IPs
27+
- SmtpServer__AllowedIps=*
2228
restart: unless-stopped
2329

2430
# Example: Papercut with TLS/STARTTLS support
@@ -36,19 +42,20 @@ services:
3642
# Mount certificate directory (adjust path to your cert location)
3743
# - /path/to/certs:/certs:ro
3844
environment:
39-
- IP=Any
40-
- Port=587
45+
- SmtpServer__IP=Any
46+
- SmtpServer__Port=587
47+
- SmtpServer__AllowedIps=*
4148
# TLS/STARTTLS Configuration
4249
# Uncomment and configure these to enable TLS
4350
# Simple approach - use certificate by name (most common):
44-
- CertificateFindType=FindBySubjectName
45-
- CertificateFindValue=localhost
46-
# - CertificateStoreLocation=LocalMachine
47-
# - CertificateStoreName=My
51+
- SmtpServer__CertificateFindType=FindBySubjectName
52+
- SmtpServer__CertificateFindValue=localhost
53+
# - SmtpServer__CertificateStoreLocation=LocalMachine
54+
# - SmtpServer__CertificateStoreName=My
4855
#
4956
# Alternative - use thumbprint (more specific but harder to use):
50-
# - CertificateFindType=FindByThumbprint
51-
# - CertificateFindValue=YOUR_CERT_THUMBPRINT_HERE
57+
# - SmtpServer__CertificateFindType=FindByThumbprint
58+
# - SmtpServer__CertificateFindValue=YOUR_CERT_THUMBPRINT_HERE
5259
restart: unless-stopped
5360

5461
# Example: Multiple ports (plain SMTP + STARTTLS)
@@ -101,3 +108,22 @@ volumes:
101108
# Testing TLS:
102109
# openssl s_client -connect localhost:587 -starttls smtp
103110
# # Should show STARTTLS in EHLO response
111+
112+
# IP Allowlist Configuration:
113+
#
114+
# The SmtpServer__AllowedIps environment variable controls which IP addresses
115+
# can connect to the SMTP server. This provides additional security.
116+
#
117+
# Syntax:
118+
# - SmtpServer__AllowedIps=* # Allow all IPs (default)
119+
# - SmtpServer__AllowedIps=192.168.1.0/24 # Allow single CIDR range
120+
# - SmtpServer__AllowedIps=192.168.1.0/24,10.0.0.0/8 # Allow multiple CIDR ranges
121+
# - SmtpServer__AllowedIps=192.168.1.100 # Allow single IP
122+
# - SmtpServer__AllowedIps=192.168.1.100,192.168.1.101 # Allow multiple IPs
123+
#
124+
# Notes:
125+
# - Applies only to SMTP connections, not HTTP web UI access
126+
# - Localhost (127.0.0.1/::1) is always allowed for SMTP
127+
# - IPv4 and IPv6 are both supported
128+
# - CIDR notation allows efficient network range specification
129+
# - Changes require container restart

examples/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<!-- Common properties for all example projects -->
33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

installation/winget/ChangemakerStudios.PapercutSMTP.installer.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PackageIdentifier: "ChangemakerStudios.PapercutSMTP"
2-
PackageVersion: "7.5.1"
2+
PackageVersion: "7.6.0"
33
Platform:
44
- "Windows.Desktop"
55
MinimumOSVersion: "10.0.17763.0"
@@ -13,13 +13,13 @@ InstallerSwitches:
1313
UpgradeBehavior: "install"
1414
Installers:
1515
- Architecture: "x64"
16-
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.5.1/PapercutSMTP-win-x64-stable-Setup.exe"
16+
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.6.0/PapercutSMTP-win-x64-stable-Setup.exe"
1717
InstallerSha256: "<SHA256_HASH_x64>"
1818
- Architecture: "x86"
19-
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.5.1/PapercutSMTP-win-x86-stable-Setup.exe"
19+
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.6.0/PapercutSMTP-win-x86-stable-Setup.exe"
2020
InstallerSha256: "<SHA256_HASH_x86>"
2121
- Architecture: "arm64"
22-
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.5.1/PapercutSMTP-win-arm64-stable-Setup.exe"
22+
InstallerUrl: "https://github.com/ChangemakerStudios/Papercut-SMTP/releases/download/7.6.0/PapercutSMTP-win-arm64-stable-Setup.exe"
2323
InstallerSha256: "<SHA256_HASH_arm64>"
2424
ManifestType: "installer"
2525
ManifestVersion: "1.6.0"

0 commit comments

Comments
 (0)