1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00

config: Support "" values for drop_characters and suffix_separators

If the `drop_characters` or `suffix_separators` options are set to "",
currently instead of the empty string, their default value is used instead.

This is a bug, and it also happens on other config options, but because
the others have to be set in order for chasquid to function, it's not a
problem in practice.

Thanks Björn Busse (bbusse@github) for finding and reporting this
problem, on irc and in https://github.com/albertito/chasquid/issues/25.

This patch fixes the problem by marking these fields explicitly
optional, which enables presence testing, as described in the protobuf
documentation:
https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md.
This commit is contained in:
Alberto Bertogli
2022-01-14 01:13:31 +00:00
parent 4f595ce3d2
commit fa1db7d81a
6 changed files with 64 additions and 46 deletions

View File

@@ -102,7 +102,7 @@ func main() {
s.HookPath = "hooks/" s.HookPath = "hooks/"
s.HAProxyEnabled = conf.HaproxyIncoming s.HAProxyEnabled = conf.HaproxyIncoming
s.SetAliasesConfig(conf.SuffixSeparators, conf.DropCharacters) s.SetAliasesConfig(*conf.SuffixSeparators, *conf.DropCharacters)
if conf.DovecotAuth { if conf.DovecotAuth {
loadDovecot(s, conf.DovecotUserdbPath, conf.DovecotClientPath) loadDovecot(s, conf.DovecotUserdbPath, conf.DovecotClientPath)

View File

@@ -225,8 +225,8 @@ func aliasesResolve() {
_ = os.Chdir(configDir) _ = os.Chdir(configDir)
r := aliases.NewResolver() r := aliases.NewResolver()
r.SuffixSep = conf.SuffixSeparators r.SuffixSep = *conf.SuffixSeparators
r.DropChars = conf.DropCharacters r.DropChars = *conf.DropCharacters
domainDirs, err := ioutil.ReadDir("domains/") domainDirs, err := ioutil.ReadDir("domains/")
if err != nil { if err != nil {
@@ -316,8 +316,8 @@ func aliasesAdd() {
// Setup alias resolver. // Setup alias resolver.
r := aliases.NewResolver() r := aliases.NewResolver()
r.SuffixSep = conf.SuffixSeparators r.SuffixSep = *conf.SuffixSeparators
r.DropChars = conf.DropCharacters r.DropChars = *conf.DropCharacters
r.AddDomain(domain) r.AddDomain(domain)
aliasesFilePath := filepath.Join("domains", domain, "aliases") aliasesFilePath := filepath.Join("domains", domain, "aliases")

View File

@@ -2,7 +2,7 @@
package config package config
// Generate the config protobuf. // Generate the config protobuf.
//go:generate protoc --go_out=. --go_opt=paths=source_relative config.proto //go:generate protoc --go_out=. --go_opt=paths=source_relative --experimental_allow_proto3_optional config.proto
import ( import (
"fmt" "fmt"
@@ -27,8 +27,8 @@ var defaultConfig = &Config{
DataDir: "/var/lib/chasquid", DataDir: "/var/lib/chasquid",
SuffixSeparators: "+", SuffixSeparators: proto.String("+"),
DropCharacters: ".", DropCharacters: proto.String("."),
MailLogPath: "<syslog>", MailLogPath: "<syslog>",
} }
@@ -104,10 +104,10 @@ func override(c, o *Config) {
c.DataDir = o.DataDir c.DataDir = o.DataDir
} }
if o.SuffixSeparators != "" { if o.SuffixSeparators != nil {
c.SuffixSeparators = o.SuffixSeparators c.SuffixSeparators = o.SuffixSeparators
} }
if o.DropCharacters != "" { if o.DropCharacters != nil {
c.DropCharacters = o.DropCharacters c.DropCharacters = o.DropCharacters
} }
if o.MailLogPath != "" { if o.MailLogPath != "" {
@@ -140,8 +140,16 @@ func LogConfig(c *Config) {
log.Infof(" Monitoring address: %s", c.MonitoringAddress) log.Infof(" Monitoring address: %s", c.MonitoringAddress)
log.Infof(" MDA: %s %v", c.MailDeliveryAgentBin, c.MailDeliveryAgentArgs) log.Infof(" MDA: %s %v", c.MailDeliveryAgentBin, c.MailDeliveryAgentArgs)
log.Infof(" Data directory: %s", c.DataDir) log.Infof(" Data directory: %s", c.DataDir)
log.Infof(" Suffix separators: %s", c.SuffixSeparators) if c.SuffixSeparators == nil {
log.Infof(" Drop characters: %s", c.DropCharacters) log.Infof(" Suffix separators: nil")
} else {
log.Infof(" Suffix separators: %s", *c.SuffixSeparators)
}
if c.DropCharacters == nil {
log.Infof(" Drop characters: nil")
} else {
log.Infof(" Drop characters: %s", *c.DropCharacters)
}
log.Infof(" Mail log: %s", c.MailLogPath) log.Infof(" Mail log: %s", c.MailLogPath)
log.Infof(" Dovecot auth: %v (%q, %q)", log.Infof(" Dovecot auth: %v (%q, %q)",
c.DovecotAuth, c.DovecotUserdbPath, c.DovecotClientPath) c.DovecotAuth, c.DovecotUserdbPath, c.DovecotClientPath)

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.26.0 // protoc-gen-go v1.27.1
// protoc v3.12.4 // protoc v3.12.4
// source: config.proto // source: config.proto
@@ -80,12 +80,12 @@ type Config struct {
// Including "+" is strongly encouraged, as it is assumed for email // Including "+" is strongly encouraged, as it is assumed for email
// forwarding. // forwarding.
// Default: "+". // Default: "+".
SuffixSeparators string `protobuf:"bytes,10,opt,name=suffix_separators,json=suffixSeparators,proto3" json:"suffix_separators,omitempty"` SuffixSeparators *string `protobuf:"bytes,10,opt,name=suffix_separators,json=suffixSeparators,proto3,oneof" json:"suffix_separators,omitempty"`
// Characters to drop from the user part on local emails. // Characters to drop from the user part on local emails.
// For example, if you set this to "._", email to local user // For example, if you set this to "._", email to local user
// "u.se_r" will be delivered to "user". // "u.se_r" will be delivered to "user".
// Default: ".". // Default: ".".
DropCharacters string `protobuf:"bytes,11,opt,name=drop_characters,json=dropCharacters,proto3" json:"drop_characters,omitempty"` DropCharacters *string `protobuf:"bytes,11,opt,name=drop_characters,json=dropCharacters,proto3,oneof" json:"drop_characters,omitempty"`
// Path where to write the mail log to. // Path where to write the mail log to.
// If "<syslog>", log using the syslog (at MAIL|INFO priority). // If "<syslog>", log using the syslog (at MAIL|INFO priority).
// If "<stdout>", log to stdout; if "<stderr>", log to stderr. // If "<stdout>", log to stdout; if "<stderr>", log to stderr.
@@ -205,15 +205,15 @@ func (x *Config) GetDataDir() string {
} }
func (x *Config) GetSuffixSeparators() string { func (x *Config) GetSuffixSeparators() string {
if x != nil { if x != nil && x.SuffixSeparators != nil {
return x.SuffixSeparators return *x.SuffixSeparators
} }
return "" return ""
} }
func (x *Config) GetDropCharacters() string { func (x *Config) GetDropCharacters() string {
if x != nil { if x != nil && x.DropCharacters != nil {
return x.DropCharacters return *x.DropCharacters
} }
return "" return ""
} }
@@ -256,7 +256,7 @@ func (x *Config) GetHaproxyIncoming() bool {
var File_config_proto protoreflect.FileDescriptor var File_config_proto protoreflect.FileDescriptor
var file_config_proto_rawDesc = []byte{ var file_config_proto_rawDesc = []byte{
0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf4,
0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73,
0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73,
0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74,
@@ -282,29 +282,32 @@ var file_config_proto_rawDesc = []byte{
0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x6d, 0x61, 0x69, 0x6c, 0x44, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x6d, 0x61, 0x69, 0x6c, 0x44, 0x65, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x73, 0x12, 0x19, 0x69, 0x76, 0x65, 0x72, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x73, 0x12, 0x19,
0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x64, 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x75, 0x66, 0x52, 0x07, 0x64, 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x12, 0x30, 0x0a, 0x11, 0x73, 0x75, 0x66,
0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0a, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0a,
0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x53, 0x65, 0x70, 0x61, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x53, 0x65,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x0f, 0x64,
0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0b,
0x0e, 0x64, 0x72, 0x6f, 0x70, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x12, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0e, 0x64, 0x72, 0x6f, 0x70, 0x43, 0x68, 0x61, 0x72,
0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x69,
0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x69, 0x6c, 0x4c, 0x6f, 0x67, 0x50, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09,
0x61, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x5f, 0x61, 0x52, 0x0b, 0x6d, 0x61, 0x69, 0x6c, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, 0x0a,
0x75, 0x74, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x0c, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x0d, 0x20,
0x6f, 0x74, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x41, 0x75, 0x74, 0x68,
0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72,
0x01, 0x28, 0x09, 0x52, 0x11, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x55, 0x73, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x64,
0x64, 0x62, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x55, 0x73, 0x65, 0x72, 0x64, 0x62, 0x50, 0x61, 0x74, 0x68,
0x74, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x65,
0x01, 0x28, 0x09, 0x52, 0x11, 0x64, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x64,
0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x68, 0x61, 0x70, 0x72, 0x6f, 0x78, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68,
0x79, 0x5f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x12, 0x29, 0x0a, 0x10, 0x68, 0x61, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x69, 0x6e, 0x63, 0x6f,
0x52, 0x0f, 0x68, 0x61, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x68, 0x61, 0x70, 0x72,
0x67, 0x42, 0x2c, 0x5a, 0x2a, 0x62, 0x6c, 0x69, 0x74, 0x69, 0x72, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x78, 0x79, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x42, 0x14, 0x0a, 0x12, 0x5f,
0x2e, 0x61, 0x72, 0x2f, 0x67, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x73, 0x71, 0x75, 0x69, 0x64, 0x2f, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x73, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x63, 0x74, 0x65, 0x72, 0x73, 0x42, 0x2c, 0x5a, 0x2a, 0x62, 0x6c, 0x69, 0x74, 0x69, 0x72, 0x69,
0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x2f, 0x67, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x73, 0x71,
0x75, 0x69, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@@ -350,6 +353,7 @@ func file_config_proto_init() {
} }
} }
} }
file_config_proto_msgTypes[0].OneofWrappers = []interface{}{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@@ -67,13 +67,13 @@ message Config {
// Including "+" is strongly encouraged, as it is assumed for email // Including "+" is strongly encouraged, as it is assumed for email
// forwarding. // forwarding.
// Default: "+". // Default: "+".
string suffix_separators = 10; optional string suffix_separators = 10;
// Characters to drop from the user part on local emails. // Characters to drop from the user part on local emails.
// For example, if you set this to "._", email to local user // For example, if you set this to "._", email to local user
// "u.se_r" will be delivered to "user". // "u.se_r" will be delivered to "user".
// Default: ".". // Default: ".".
string drop_characters = 11; optional string drop_characters = 11;
// Path where to write the mail log to. // Path where to write the mail log to.
// If "<syslog>", log using the syslog (at MAIL|INFO priority). // If "<syslog>", log using the syslog (at MAIL|INFO priority).

View File

@@ -24,6 +24,10 @@ func mustCreateConfig(t *testing.T, contents string) (string, string) {
return tmpDir, tmpDir + "/chasquid.conf" return tmpDir, tmpDir + "/chasquid.conf"
} }
func TestEmptyStruct(t *testing.T) {
testLogConfig(&Config{})
}
func TestEmptyConfig(t *testing.T) { func TestEmptyConfig(t *testing.T) {
tmpDir, path := mustCreateConfig(t, "") tmpDir, path := mustCreateConfig(t, "")
defer testlib.RemoveIfOk(t, tmpDir) defer testlib.RemoveIfOk(t, tmpDir)
@@ -54,6 +58,7 @@ func TestFullConfig(t *testing.T) {
submission_address: ":10002" submission_address: ":10002"
monitoring_address: ":1111" monitoring_address: ":1111"
max_data_size_mb: 26 max_data_size_mb: 26
suffix_separators: ""
` `
tmpDir, path := mustCreateConfig(t, confStr) tmpDir, path := mustCreateConfig(t, confStr)
@@ -63,6 +68,7 @@ func TestFullConfig(t *testing.T) {
hostname: "proust" hostname: "proust"
submission_address: ":999" submission_address: ":999"
dovecot_auth: true dovecot_auth: true
drop_characters: ""
` `
expected := &Config{ expected := &Config{
@@ -79,8 +85,8 @@ func TestFullConfig(t *testing.T) {
DataDir: "/var/lib/chasquid", DataDir: "/var/lib/chasquid",
SuffixSeparators: "+", SuffixSeparators: proto.String(""),
DropCharacters: ".", DropCharacters: proto.String(""),
MailLogPath: "<syslog>", MailLogPath: "<syslog>",