Documentation ¶
Overview ¶
Package mox provides functions dealing with global state, such as the current configuration, and convenience functions.
Index ¶
- Variables
- func AcceptsGzip(r *http.Request) bool
- func AccountAdd(ctx context.Context, account, address string) (rerr error)
- func AccountRemove(ctx context.Context, account string) (rerr error)
- func AccountSave(ctx context.Context, account string, xmodify func(acc *config.Account)) (rerr error)
- func AddressAdd(ctx context.Context, address, account string) (rerr error)
- func AddressRemove(ctx context.Context, address string) (rerr error)
- func AliasAdd(ctx context.Context, addr smtp.Address, alias config.Alias) error
- func AliasAddressesAdd(ctx context.Context, addr smtp.Address, addresses []string) error
- func AliasAddressesRemove(ctx context.Context, addr smtp.Address, addresses []string) error
- func AliasRemove(ctx context.Context, addr smtp.Address) error
- func AliasUpdate(ctx context.Context, addr smtp.Address, alias config.Alias) error
- func AllowMsgFrom(accountName string, msgFrom smtp.Address) bool
- func CanonicalLocalpart(localpart smtp.Localpart, d config.Domain) smtp.Localpart
- func Cid() int64
- func CidFromCtx(ctx context.Context) int64
- func CleanupPassedFiles()
- func ConfigDirPath(f string) string
- func ConfigSave(ctx context.Context, xmodify func(config *config.Dynamic)) (rerr error)
- func CryptoRandInt() int64
- func DKIMAdd(ctx context.Context, domain, selector dns.Domain, algorithm, hash string, ...) (rerr error)
- func DKIMRemove(ctx context.Context, domain, selector dns.Domain) (rerr error)
- func DKIMSelectors(dkimConf config.DKIM) []dkim.Selector
- func DKIMSign(ctx context.Context, log mlog.Log, from smtp.Path, smtputf8 bool, data []byte) (string, error)
- func DataDirPath(f string) string
- func DomainAdd(ctx context.Context, domain dns.Domain, accountName string, ...) (rerr error)
- func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool, ...) ([]string, error)
- func DomainRemove(ctx context.Context, domain dns.Domain) (rerr error)
- func DomainSPFIPs() (ips []net.IP)
- func DomainSave(ctx context.Context, domainName string, ...) (rerr error)
- func FallbackMtime(log mlog.Log) time.Time
- func FillExample(seen []reflect.Type, rv reflect.Value) reflect.Value
- func FillNil(rv reflect.Value) (nv reflect.Value, changed bool)
- func ForkExecUnprivileged()
- func IPs(ctx context.Context, receiveOnly bool) ([]net.IP, error)
- func LastKnown() (current, lastknown updates.Version, mtime time.Time, rerr error)
- func LicensesWrite(dst io.Writer) error
- func LimitersInit()
- func Listen(network, addr string) (net.Listener, error)
- func LoadConfig(ctx context.Context, log mlog.Log, doLoadTLSKeyCerts, checkACMEHosts bool) []error
- func LocalserveNeedsError(lp smtp.Localpart) (code int, timeout bool)
- func LookupAddress(localpart smtp.Localpart, domain dns.Domain, allowPostmaster, allowAlias bool) (accountName string, alias *config.Alias, canonicalAddress string, ...)
- func MakeAccountConfig(addr smtp.Address) config.Account
- func MakeDKIMEd25519Key(selector, domain dns.Domain) ([]byte, error)
- func MakeDKIMRSAKey(selector, domain dns.Domain) ([]byte, error)
- func MakeDomainConfig(ctx context.Context, domain, hostname dns.Domain, accountName string, ...) (config.Domain, []string, error)
- func MessageIDGen(smtputf8 bool) string
- func MustLoadConfig(doLoadTLSKeyCerts, checkACMEHosts bool)
- func Network(ip string) string
- func NewPseudoRand() *rand
- func OpenPrivileged(path string) (*os.File, error)
- func ParseDynamicConfig(ctx context.Context, log mlog.Log, dynamicPath string, static config.Static) (c config.Dynamic, mtime time.Time, accDests map[string]AccountDestination, ...)
- func PrepareStaticConfig(ctx context.Context, log mlog.Log, configFile string, conf *Config, ...) (errs []error)
- func ReceivedID(cid int64) string
- func ReceivedIDInit(key, rand []byte) error
- func ReceivedToCid(s string) (cid int64, err error)
- func RestorePassedFiles()
- func SafeHeaders(fn http.Handler) http.Handler
- func SetConfig(c *Config)
- func SetPedantic(p bool)
- func Sleep(ctx context.Context, d time.Duration)
- func StoreLastKnown(v updates.Version) error
- func TLSReceivedComment(log mlog.Log, cs tls.ConnectionState) []string
- func TXTStrings(s string) string
- type AccountDestination
- type ClientConfig
- type ClientConfigs
- type ClientConfigsEntry
- type Config
- func (c *Config) Account(name string) (acc config.Account, ok bool)
- func (c *Config) AccountDestination(addr string) (accDest AccountDestination, alias *config.Alias, ok bool)
- func (c *Config) Accounts() (l []string)
- func (c *Config) Domain(d dns.Domain) (dom config.Domain, ok bool)
- func (c *Config) DomainLocalparts(d dns.Domain) (map[string]string, map[string]config.Alias)
- func (c *Config) Domains() (l []string)
- func (c *Config) DynamicConfig() (config config.Dynamic)
- func (c *Config) IsClientSettingsDomain(d dns.Domain) (is bool)
- func (c *Config) LogLevelRemove(log mlog.Log, pkg string)
- func (c *Config) LogLevelSet(log mlog.Log, pkg string, level slog.Level)
- func (c *Config) LogLevels() map[string]slog.Level
- func (c *Config) Routes(accountName string, domain dns.Domain) (accountRoutes, domainRoutes, globalRoutes []config.Route)
- type ProtocolConfig
- type TLSMode
- type WebappFile
Constants ¶
This section is empty.
Variables ¶
var ( ConfigStaticPath string ConfigDynamicPath string Conf = Config{Log: map[string]slog.Level{"": slog.LevelError}} )
Config paths are set early in program startup. They will point to files in the same directory.
var ( ErrDomainNotFound = errors.New("domain not found") ErrAddressNotFound = errors.New("address not found") )
var Connections = &connections{ conns: map[net.Conn]connKind{}, gauges: map[connKind]prometheus.GaugeFunc{}, active: map[connKind]int64{}, }
Connections holds all active protocol sockets (smtp, imap). They will be given an immediate read/write deadline shortly after initiating mox shutdown, after which the connections get 1 more second for error handling before actual shutdown.
var Context context.Context
This context should be used as parent by most operations. It is canceled 1 second after graceful shutdown was initiated with the cancelation of the Shutdown context. This should abort active operations.
Operations typically have context timeouts, 30s for single i/o like DNS queries, and 1 minute for operations with more back and forth. These are set through a context.WithTimeout based on this context, so those contexts are still canceled when shutting down.
HTTP servers don't get graceful shutdown, their connections are just aborted. todo: should shut down http connections as well, and shut down the listener and/or return 503 for new requests.
var ContextCancel func()
var ErrConfig = errors.New("config error")
var ErrRequest = errors.New("bad request")
var FilesImmediate bool
For privileged file descriptor operations (listen and opening privileged files), perform them immediately, regardless of running as root or other user, in case ForkExecUnprivileged is not used.
var LicensesFsys fs.FS
var LimiterFailedAuth *ratelimit.Limiter
var NewWebaccountHandler = func(basePath string, isForwarded bool) http.Handler { return nopHandler }
var NewWebadminHandler = func(basePath string, isForwarded bool) http.Handler { return nopHandler }
Set by packages webadmin, webaccount, webmail, webapisrv to prevent cyclic dependencies.
var NewWebapiHandler = func(maxMsgSize int64, basePath string, isForwarded bool) http.Handler { return nopHandler }
var NewWebmailHandler = func(maxMsgSize int64, basePath string, isForwarded bool, accountPath string) http.Handler {
return nopHandler
}
var Pedantic bool
Pedantic enables stricter parsing.
var Shutdown context.Context
Shutdown is canceled when a graceful shutdown is initiated. SMTP, IMAP, periodic processes should check this before starting a new operation. If this context is canaceled, the operation should not be started, and new connections/commands should receive a message that the service is currently not available.
var ShutdownCancel func()
Functions ¶
func AcceptsGzip ¶ added in v0.0.9
AcceptsGzip returns whether the client accepts gzipped responses.
func AccountAdd ¶
AccountAdd adds an account and an initial address and reloads the configuration.
The new account does not have a password, so cannot yet log in. Email can be delivered.
Catchall addresses are not supported for AccountAdd. Add separately with AddressAdd.
func AccountRemove ¶
AccountRemove removes an account and reloads the configuration.
func AccountSave ¶ added in v0.0.11
func AccountSave(ctx context.Context, account string, xmodify func(acc *config.Account)) (rerr error)
AccountSave updates the configuration of an account. Function xmodify is called with a shallow copy of the current configuration of the account. It must not change referencing fields (e.g. existing slice/map/pointer), they may still be in use, and the change may be rolled back. Referencing values must be copied and replaced by the modify. The function may raise a panic for error handling.
func AddressAdd ¶
AddressAdd adds an email address to an account and reloads the configuration. If address starts with an @ it is treated as a catchall address for the domain.
func AddressRemove ¶
AddressRemove removes an email address and reloads the configuration. Address can be a catchall address for the domain of the form "@<domain>".
If the address is member of an alias, remove it from from the alias, unless it is the last member.
func AliasAddressesAdd ¶ added in v0.0.11
func AliasAddressesRemove ¶ added in v0.0.11
func AliasUpdate ¶ added in v0.0.11
func AllowMsgFrom ¶ added in v0.0.11
AllowMsgFrom returns whether account is allowed to submit messages with address as message From header, based on configured addresses and membership of aliases that allow using its address.
func CanonicalLocalpart ¶
CanonicalLocalpart returns the canonical localpart, removing optional catchall separator, and optionally lower-casing the string.
func Cid ¶
func Cid() int64
Cid returns a new unique id to be used for connections/sessions/requests.
func CidFromCtx ¶ added in v0.0.2
CidFromCtx returns the cid in the context, or 0.
func CleanupPassedFiles ¶ added in v0.0.4
func CleanupPassedFiles()
CleanupPassedFiles closes the listening socket file descriptors and files passed in by the parent process. To be called by the unprivileged child after listeners have been recreated (they dup the file descriptor), and by the privileged process after starting its child.
func ConfigDirPath ¶
ConfigDirPath returns the path to "f". Either f itself when absolute, or interpreted relative to the directory of the current config file.
func ConfigSave ¶ added in v0.0.11
ConfigSave calls xmodify with a shallow copy of the dynamic config. xmodify can modify the config, but must clone all referencing data it changes. xmodify may employ panic-based error handling. After xmodify returns, the modified config is verified, saved and takes effect.
func CryptoRandInt ¶
func CryptoRandInt() int64
CryptoRandInt returns a cryptographically random number.
func DKIMAdd ¶ added in v0.0.11
func DKIMAdd(ctx context.Context, domain, selector dns.Domain, algorithm, hash string, headerRelaxed, bodyRelaxed, seal bool, headers []string, lifetime time.Duration) (rerr error)
DKIMAdd adds a DKIM selector for a domain, generating a key and writing it to disk.
func DKIMRemove ¶ added in v0.0.11
DKIMRemove removes the selector from the domain, moving the key file out of the way.
func DKIMSelectors ¶ added in v0.0.9
DKIMSelectors returns the selectors to use for signing.
func DKIMSign ¶ added in v0.0.9
func DKIMSign(ctx context.Context, log mlog.Log, from smtp.Path, smtputf8 bool, data []byte) (string, error)
DKIMSign looks up the domain for "from", and uses its DKIM configuration to generate DKIM-Signature headers, for inclusion in a message. The DKIM-Signatur headers, are returned. If no domain was found an empty string and nil error is returned.
func DataDirPath ¶
DataDirPath returns to the path to "f". Either f itself when absolute, or interpreted relative to the data directory from the currently active configuration.
func DomainAdd ¶
func DomainAdd(ctx context.Context, domain dns.Domain, accountName string, localpart smtp.Localpart) (rerr error)
DomainAdd adds the domain to the domains config, rewriting domains.conf and marking it loaded.
accountName is used for DMARC/TLS report and potentially for the postmaster address. If the account does not exist, it is created with localpart. Localpart must be set only if the account does not yet exist.
func DomainRecords ¶
func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool, certIssuerDomainName, acmeAccountURI string) ([]string, error)
DomainRecords returns text lines describing DNS records required for configuring a domain.
If certIssuerDomainName is set, CAA records to limit TLS certificate issuance to that caID will be suggested. If acmeAccountURI is also set, CAA records also restricting issuance to that account ID will be suggested.
func DomainRemove ¶
DomainRemove removes domain from the config, rewriting domains.conf.
No accounts are removed, also not when they still reference this domain.
func DomainSPFIPs ¶ added in v0.0.12
DomainSPFIPs returns IPs to include in SPF records for domains. It includes the IPs on listeners that have SMTP enabled, and includes IPs configured for SOCKS transports.
func DomainSave ¶ added in v0.0.11
func DomainSave(ctx context.Context, domainName string, xmodify func(config *config.Domain) error) (rerr error)
DomainSave calls xmodify with a shallow copy of the domain config. xmodify can modify the config, but must clone all referencing data it changes. xmodify may employ panic-based error handling. After xmodify returns, the modified config is verified, saved and takes effect.
func FallbackMtime ¶ added in v0.0.9
FallbackMtime returns a time to use for the Last-Modified header in case we cannot find a file, e.g. when used in production.
func FillExample ¶ added in v0.0.11
FillExample returns a modified value with nil/empty maps/slices/pointers values replaced with non-empty versions, for more helpful examples of types. Useful for documenting JSON representations of types.
func FillNil ¶ added in v0.0.11
FillNil returns a modified value with nil maps/slices replaced with empty maps/slices.
func ForkExecUnprivileged ¶ added in v0.0.2
func ForkExecUnprivileged()
Fork and exec as unprivileged user.
We don't use just setuid because it is hard to guarantee that no other privileged go worker processes have been started before we get here. E.g. init functions in packages can start goroutines.
func IPs ¶
IPs returns ip addresses we may be listening/receiving mail on or connecting/sending from to the outside.
func LastKnown ¶
LastKnown returns the last known version that has been mentioned in an update email, or the current application.
func LicensesWrite ¶ added in v0.0.12
LicensesWrite writes the licenses to dst.
func Listen ¶ added in v0.0.2
Listen returns a newly created network listener when starting as root, and otherwise (not root) returns a network listener from a file descriptor that was passed by the parent root process.
func LoadConfig ¶
LoadConfig attempts to parse and load a config, returning any errors encountered.
func LocalserveNeedsError ¶ added in v0.0.11
func LookupAddress ¶ added in v0.0.11
func LookupAddress(localpart smtp.Localpart, domain dns.Domain, allowPostmaster, allowAlias bool) (accountName string, alias *config.Alias, canonicalAddress string, dest config.Destination, rerr error)
FindAccount looks up the account for localpart and domain.
Can return ErrDomainNotFound and ErrAddressNotFound.
func MakeAccountConfig ¶
MakeAccountConfig returns a new account configuration for an email address.
func MakeDKIMEd25519Key ¶
MakeDKIMEd25519Key returns a PEM buffer containing an ed25519 key for use with DKIM. selector and domain can be empty. If not, they are used in the note.
func MakeDKIMRSAKey ¶
MakeDKIMRSAKey returns a PEM buffer containing an rsa key for use with DKIM. selector and domain can be empty. If not, they are used in the note.
func MakeDomainConfig ¶
func MakeDomainConfig(ctx context.Context, domain, hostname dns.Domain, accountName string, withMTASTS bool) (config.Domain, []string, error)
MakeDomainConfig makes a new config for a domain, creating DKIM keys, using accountName for DMARC and TLS reports.
func MessageIDGen ¶
MessageIDGen returns a generated unique random Message-Id value, excluding <>.
func MustLoadConfig ¶
func MustLoadConfig(doLoadTLSKeyCerts, checkACMEHosts bool)
MustLoadConfig loads the config, quitting on errors.
func Network ¶
Network returns tcp4 or tcp6, depending on the ip. This network can be passed to Listen instead of "tcp", which may start listening on both ipv4 and ipv6 for addresses 0.0.0.0 and ::, which can lead to errors about the port already being in use. For invalid IPs, "tcp" is returned.
func NewPseudoRand ¶ added in v0.0.8
func NewPseudoRand() *rand
NewPseudoRand returns a new PRNG seeded with random bytes from crypto/rand. Its functions can be called concurrently.
func OpenPrivileged ¶ added in v0.0.4
Open a privileged file, such as a TLS private key. When running as root (during startup), the file is opened and the file descriptor is stored. These file descriptors are passed to the unprivileged process. When in the unprivileged processed, we lookup a passed file descriptor. The same calls should be made in the privileged and unprivileged process.
func ParseDynamicConfig ¶
func ParseDynamicConfig(ctx context.Context, log mlog.Log, dynamicPath string, static config.Static) (c config.Dynamic, mtime time.Time, accDests map[string]AccountDestination, aliases map[string]config.Alias, errs []error)
PrepareDynamicConfig parses the dynamic config file given a static file.
func PrepareStaticConfig ¶
func PrepareStaticConfig(ctx context.Context, log mlog.Log, configFile string, conf *Config, checkOnly, doLoadTLSKeyCerts bool) (errs []error)
PrepareStaticConfig parses the static config file and prepares data structures for starting mox. If checkOnly is set no substantial changes are made, like creating an ACME registration.
func ReceivedID ¶
ReceivedID returns an ID for use in a message Received header.
The ID is based on the cid. The cid itself is a counter and would leak the number of connections in received headers. Instead they are obfuscated by encrypting them with AES with a per-install key and random buffer. This allows recovery of the cid based on the id. See subcommand cid.
func ReceivedIDInit ¶
ReceivedIDInit sets an AES key (must be 16 bytes) and random buffer (must be 8 bytes) for use by ReceivedID.
func ReceivedToCid ¶
ReceivedToCid returns the cid given a ReceivedID.
func RestorePassedFiles ¶ added in v0.0.4
func RestorePassedFiles()
RestorePassedFiles reads addresses from $MOX_SOCKETS and paths from $MOX_FILES and prepares an os.File for each file descriptor, which are used by later calls of Listen or opening files.
func SafeHeaders ¶ added in v0.0.12
Set some http headers that should prevent potential abuse. Better safe than sorry.
func SetConfig ¶
func SetConfig(c *Config)
SetConfig sets a new config. Not to be used during normal operation.
func Sleep ¶
Sleep for d, but return as soon as ctx is done.
Used for a few places where sleep is used to push back on clients, but where shutting down should abort the sleep.
func StoreLastKnown ¶
StoreLastKnown stores the the last known version. Future update checks compare against it, or the currently running version, whichever is newer.
func TLSReceivedComment ¶ added in v0.0.9
func TLSReceivedComment(log mlog.Log, cs tls.ConnectionState) []string
TLSReceivedComment returns a comment about TLS of the connection for use in a Receive header.
func TXTStrings ¶
TXTStrings returns a TXT record value as one or more quoted strings, each max 100 characters. In case of multiple strings, a multi-line record is returned.
Types ¶
type AccountDestination ¶
type ClientConfig ¶
type ClientConfig struct { IMAP ProtocolConfig Submission ProtocolConfig }
func ClientConfigDomain ¶
func ClientConfigDomain(d dns.Domain) (rconfig ClientConfig, rerr error)
ClientConfigDomain returns a single IMAP and Submission client configuration for a domain.
type ClientConfigs ¶ added in v0.0.7
type ClientConfigs struct {
Entries []ClientConfigsEntry
}
ClientConfigs holds the client configuration for IMAP/Submission for a domain.
func ClientConfigsDomain ¶ added in v0.0.7
func ClientConfigsDomain(d dns.Domain) (ClientConfigs, error)
ClientConfigsDomain returns the client configs for IMAP/Submission for a domain.
type ClientConfigsEntry ¶ added in v0.0.7
type Config ¶
type Config struct { Static config.Static // Does not change during the lifetime of a running instance. Log map[string]slog.Level Dynamic config.Dynamic // Can only be accessed directly by tests. Use methods on Config for locked access. DynamicLastCheck time.Time // For use by quickstart only to skip checks. // contains filtered or unexported fields }
Config as used in the code, a processed version of what is in the config file.
Use methods to lookup a domain/account/address in the dynamic configuration.
func ParseConfig ¶
func ParseConfig(ctx context.Context, log mlog.Log, p string, checkOnly, doLoadTLSKeyCerts, checkACMEHosts bool) (c *Config, errs []error)
ParseConfig parses the static config at path p. If checkOnly is true, no changes are made, such as registering ACME identities. If doLoadTLSKeyCerts is true, the TLS KeyCerts configuration is loaded and checked. This is used during the quickstart in the case the user is going to provide their own certificates. If checkACMEHosts is true, the hosts allowed for acme are compared with the explicitly configured ips we are listening on.
func (*Config) AccountDestination ¶
func (*Config) DomainLocalparts ¶
DomainLocalparts returns a mapping of encoded localparts to account names for a domain, and encoded localparts to aliases. An empty localpart is a catchall destination for a domain.
func (*Config) DynamicConfig ¶ added in v0.0.11
DynamicConfig returns a shallow copy of the dynamic config. Must not be modified.
func (*Config) IsClientSettingsDomain ¶ added in v0.0.12
func (*Config) LogLevelRemove ¶
LogLevelRemove removes a configured log level for a package.
func (*Config) LogLevelSet ¶
LogLevelSet sets a new log level for pkg. An empty pkg sets the default log value that is used if no explicit log level is configured for a package. This change is ephemeral, no config file is changed.
type ProtocolConfig ¶ added in v0.0.7
type WebappFile ¶ added in v0.0.9
type WebappFile struct {
HTML, JS []byte // Embedded html/js data.
HTMLPath, JSPath string // Paths to load html/js from during development.
sync.Mutex
// contains filtered or unexported fields
}
WebappFile serves a merged HTML and JS webapp as a single compressed, cacheable file. It merges the JS into the HTML at first load, caches a gzipped version that is generated on first need, and responds with a Last-Modified header.