Skip to content

Commit c9b55b8

Browse files
Merge pull request #18 from decke/allow-any-net
Allow any network and related enhancements
2 parents 2475cad + 918df65 commit c9b55b8

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

config.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package main
22

33
import (
44
"flag"
5+
"net"
56

67
"github.com/vharitonsky/iniflags"
8+
"github.com/sirupsen/logrus"
79
)
810

911
var (
@@ -21,7 +23,8 @@ var (
2123
localCert = flag.String("local_cert", "", "SSL certificate for STARTTLS/TLS")
2224
localKey = flag.String("local_key", "", "SSL private key for STARTTLS/TLS")
2325
localForceTLS = flag.Bool("local_forcetls", false, "Force STARTTLS (needs local_cert and local_key)")
24-
allowedNets = flag.String("allowed_nets", "127.0.0.1/8 ::1/128", "Networks allowed to send mails")
26+
allowedNetsStr = flag.String("allowed_nets", "127.0.0.0/8 ::1/128", "Networks allowed to send mails")
27+
allowedNets = []*net.IPNet{}
2528
allowedSender = flag.String("allowed_sender", "", "Regular expression for valid FROM EMail addresses")
2629
allowedRecipients = flag.String("allowed_recipients", "", "Regular expression for valid TO EMail addresses")
2730
allowedUsers = flag.String("allowed_users", "", "Path to file with valid users/passwords")
@@ -33,6 +36,29 @@ var (
3336
versionInfo = flag.Bool("version", false, "Show version information")
3437
)
3538

39+
40+
func setupAllowedNetworks() {
41+
for _, netstr := range splitstr(*allowedNetsStr, ' ') {
42+
baseIP, allowedNet, err := net.ParseCIDR(netstr)
43+
if err != nil {
44+
log.WithField("netstr", netstr).
45+
WithError(err).
46+
Fatal("Invalid CIDR notation in allowed_nets")
47+
}
48+
49+
// Reject any network specification where any host bits are set,
50+
// meaning the address refers to a host and not a network.
51+
if !allowedNet.IP.Equal(baseIP) {
52+
log.WithFields(logrus.Fields{
53+
"given_net": netstr,
54+
"proper_net": allowedNet,
55+
}).Fatal("Invalid network in allowed_nets (host bits set)")
56+
}
57+
58+
allowedNets = append(allowedNets, allowedNet)
59+
}
60+
}
61+
3662
func ConfigLoad() {
3763
iniflags.Parse()
3864

@@ -42,4 +68,6 @@ func ConfigLoad() {
4268
if (*remoteHost == "") {
4369
log.Warn("remote_host not set; mail will not be forwarded!")
4470
}
71+
72+
setupAllowedNetworks()
4573
}

main.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,15 @@ import (
1717
)
1818

1919
func connectionChecker(peer smtpd.Peer) error {
20-
var peerIP net.IP
21-
if addr, ok := peer.Addr.(*net.TCPAddr); ok {
22-
peerIP = net.ParseIP(addr.IP.String())
23-
} else {
24-
log.WithField("ip", addr.IP).
25-
Warn("failed to parse IP")
26-
return smtpd.Error{Code: 421, Message: "Denied"}
27-
}
20+
// This can't panic because we only have TCP listeners
21+
peerIP := peer.Addr.(*net.TCPAddr).IP
2822

29-
nets := strings.Split(*allowedNets, " ")
30-
31-
for i := range nets {
32-
_, allowedNet, _ := net.ParseCIDR(nets[i])
23+
if len(allowedNets) == 0 {
24+
// Special case: empty string means allow everything
25+
return nil
26+
}
3327

28+
for _, allowedNet := range allowedNets {
3429
if allowedNet.Contains(peerIP) {
3530
return nil
3631
}

smtprelay.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
;local_forcetls = false
3232

3333
; Networks that are allowed to send mails to us
34-
;allowed_nets = 127.0.0.1/8 ::1/128
34+
; Defaults to localhost. If set to "", then any address is allowed.
35+
;allowed_nets = 127.0.0.0/8 ::1/128
3536

3637
; Regular expression for valid FROM EMail addresses
3738
; Example: ^(.*)@localhost.localdomain$

0 commit comments

Comments
 (0)