forked from drew/smtprelay
Expand allowedUsers email field to support comma-separated and domains (#9)
* Expand allowedUsers email field to support comma-separated and domains Closes #8 * Refactor AuthFetch() to return AuthUser struct Also, this breaks out a parseLine() function which can be easily tested. * Ignore empty addrs after splitting commas This ignores a trailing comma * Add tests for auth parseLine() * Update documentation in smtprelay.ini * Fix bug where addrAllowed() was incorrectly case-sensitive * Update allowedUsers allowed domain format to require leading @ This disambiguates a local user ('john.smith') from a domain ('example.com')
This commit is contained in:
committed by
GitHub
parent
5c2e28ac36
commit
0e8986ca79
47
main.go
47
main.go
@@ -36,15 +36,58 @@ func connectionChecker(peer smtpd.Peer) error {
|
||||
return smtpd.Error{Code: 421, Message: "Denied"}
|
||||
}
|
||||
|
||||
func addrAllowed(addr string, allowedAddrs []string) bool {
|
||||
if allowedAddrs == nil {
|
||||
// If absent, all addresses are allowed
|
||||
return true
|
||||
}
|
||||
|
||||
addr = strings.ToLower(addr)
|
||||
|
||||
// Extract optional domain part
|
||||
domain := ""
|
||||
if idx := strings.LastIndex(addr, "@"); idx != -1 {
|
||||
domain = strings.ToLower(addr[idx+1:])
|
||||
}
|
||||
|
||||
// Test each address from allowedUsers file
|
||||
for _, allowedAddr := range allowedAddrs {
|
||||
allowedAddr = strings.ToLower(allowedAddr)
|
||||
|
||||
// Three cases for allowedAddr format:
|
||||
if idx := strings.Index(allowedAddr, "@"); idx == -1 {
|
||||
// 1. local address (no @) -- must match exactly
|
||||
if allowedAddr == addr {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if idx != 0 {
|
||||
// 2. email address (user@domain.com) -- must match exactly
|
||||
if allowedAddr == addr {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
// 3. domain (@domain.com) -- must match addr domain
|
||||
allowedDomain := allowedAddr[idx+1:]
|
||||
if allowedDomain == domain {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func senderChecker(peer smtpd.Peer, addr string) error {
|
||||
// check sender address from auth file if user is authenticated
|
||||
if *allowedUsers != "" && peer.Username != "" {
|
||||
_, email, err := AuthFetch(peer.Username)
|
||||
user, err := AuthFetch(peer.Username)
|
||||
if err != nil {
|
||||
return smtpd.Error{Code: 451, Message: "Bad sender address"}
|
||||
}
|
||||
|
||||
if email != "" && strings.ToLower(addr) != strings.ToLower(email) {
|
||||
if !addrAllowed(addr, user.allowedAddresses) {
|
||||
return smtpd.Error{Code: 451, Message: "Bad sender address"}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user