Skip to content

Commit

Permalink
Merge pull request #18 from decke/allow-any-net
Browse files Browse the repository at this point in the history
Allow any network and related enhancements
  • Loading branch information
JonathonReinhart committed Mar 14, 2021
2 parents 2475cad + 918df65 commit c9b55b8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 14 deletions.
30 changes: 29 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package main

import (
"flag"
"net"

"github.com/vharitonsky/iniflags"
"github.com/sirupsen/logrus"
)

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


func setupAllowedNetworks() {
for _, netstr := range splitstr(*allowedNetsStr, ' ') {
baseIP, allowedNet, err := net.ParseCIDR(netstr)
if err != nil {
log.WithField("netstr", netstr).
WithError(err).
Fatal("Invalid CIDR notation in allowed_nets")
}

// Reject any network specification where any host bits are set,
// meaning the address refers to a host and not a network.
if !allowedNet.IP.Equal(baseIP) {
log.WithFields(logrus.Fields{
"given_net": netstr,
"proper_net": allowedNet,
}).Fatal("Invalid network in allowed_nets (host bits set)")
}

allowedNets = append(allowedNets, allowedNet)
}
}

func ConfigLoad() {
iniflags.Parse()

Expand All @@ -42,4 +68,6 @@ func ConfigLoad() {
if (*remoteHost == "") {
log.Warn("remote_host not set; mail will not be forwarded!")
}

setupAllowedNetworks()
}
19 changes: 7 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,15 @@ import (
)

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

nets := strings.Split(*allowedNets, " ")

for i := range nets {
_, allowedNet, _ := net.ParseCIDR(nets[i])
if len(allowedNets) == 0 {
// Special case: empty string means allow everything
return nil
}

for _, allowedNet := range allowedNets {
if allowedNet.Contains(peerIP) {
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion smtprelay.ini
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
;local_forcetls = false

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

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

0 comments on commit c9b55b8

Please sign in to comment.